thrift_runtime_client (thrift_runtime v0.7.0)

View Source

One connection to a Thrift server, as a gen_server.

A deliberately simple client: no automatic reconnection. Any failure — connect error, socket close, per-call timeout — fails the affected calls and stops the process, so a supervisor or a pool (poolboy, pooler, a custom supervisor) sees the death immediately and replaces the worker. That makes this process safe to use as a pool worker without extra keep-alive logic.

call/4 sends a CALL envelope with the function's parameter struct, then waits for exactly one REPLY. The reply payload is decoded per the service description: field 0 is the success value, a declared exception field turns into the wire-level {error, {exception, Name, Map}} (generated clients convert it to {error, {exception, Value}} in the value's representation), and a TApplicationException into {error, {application_exception, ...}}. oneway/4 answers as soon as the message is on the wire.

The socket runs in {active, N} delivery mode, so a dead peer is noticed even while the connection is idle. Calls are serialized per connection (one outstanding request at a time); concurrent callers queue inside the client and are served in order, matching the classic Thrift client model.

Pool owners read the per-worker counters with get_stats/1 (#{calls_ok, calls_failed}; get_and_reset_stats/1 zeroes them) — the same accounting the thrift_runtime_reconnecting_client wrapper reports, minus the connection axis a single-connection client does not have.

The generated typed client modules call into this; the same map drives both:

  • host, port (required);
  • service — module implementing thrift_runtime_service (required);
  • transport — framed (default), buffered, or http: each call POSTs one Thrift message to http_path (default "/") over a keep-alive connection and waits for the response whose body is the reply. A oneway waits for the (empty) response too — HTTP is request/response. max_frame_size bounds the response body; a non-200 status fails the call with {error, {http_status, Code}};
  • protocol — binary (default), or any thrift_runtime_protocol implementation module (see thrift_runtime:protocol_module/1);
  • timeout / connect_timeout — the connect and TLS handshake wait, default 5000 ms (connect_timeout overrides the umbrella; per-call timeouts ride the call/4 argument);
  • max_frame_size — framed guard and HTTP body bound, default 64 MiB;
  • ssl_opts — a list of ssl:tls_client_option(); presence switches the connection to TLS (verify the server with verify_peer plus cacerts);
  • multiplex — the service name of a multiplexed server: outgoing message names are prefixed <<"Service:function">> (the reply keeps the plain function name, so nothing else changes). Only the name on the wire is touched; pass the same plain function names to call/4/oneway/4;
  • on_event — an observability callback (undefined by default): a 1-arity fun or {M, F, A} receiving one event map per caller-facing answer — call_ok / call_error, the same accounting get_stats/1 reports; see thrift_runtime_events.

Summary

Functions

Calls Function with Args (declaration order, wire representation) and waits for a reply.

Returns the same map as get_stats/1 and zeroes the counters.

Health-check counters for pool owners, same accounting as thrift_runtime_reconnecting_client (minus the connection axis, which a single-connection client does not have): #{calls_ok := N, calls_failed := N}. A declared exception is a completed round-trip but still counts failed, matching the {error, _} the caller sees.

Sends a one-way call; the server never answers.

Connects to the server without linking — for owners that monitor instead, such as pool workers started by a pool library.

Connects to the server and links the client to the caller; fails if the connection cannot be made.

Closes the connection; outstanding calls fail with {error, closed}.

Types

call_result()

-type call_result() ::
          {ok, term()} |
          {error, {exception, binary(), thrift_runtime_binary:struct_value()}} |
          {error, {exception, thrift_runtime_binary:struct_value()}} |
          {error, {application_exception, binary(), non_neg_integer(), binary()}} |
          {error, term()}.

options()

-type options() ::
          #{host := inet:socket_address() | inet:hostname(),
            port := inet:port_number(),
            service := module(),
            transport => thrift_runtime_socket:transport(),
            protocol => binary | compact | module(),
            timeout => pos_integer(),
            max_frame_size => pos_integer(),
            http_path => binary(),
            ssl_opts => [ssl:tls_client_option()],
            multiplex => binary(),
            active_n => pos_integer(),
            max_queue_depth => pos_integer() | infinity,
            on_event => thrift_runtime_events:handler()}.

stats()

-type stats() :: #{calls_ok := non_neg_integer(), calls_failed := non_neg_integer()}.

Functions

call(Pid, Function, Args, Timeout)

-spec call(pid(), binary(), [term()], pos_integer() | infinity) -> call_result().

Calls Function with Args (declaration order, wire representation) and waits for a reply.

For void functions the success value is undefined. Concurrent callers queue in order; only the head request is on the wire.

get_and_reset_stats(Pid)

-spec get_and_reset_stats(pid()) -> stats().

Returns the same map as get_stats/1 and zeroes the counters.

get_stats(Pid)

-spec get_stats(pid()) -> stats().

Health-check counters for pool owners, same accounting as thrift_runtime_reconnecting_client (minus the connection axis, which a single-connection client does not have): #{calls_ok := N, calls_failed := N}. A declared exception is a completed round-trip but still counts failed, matching the {error, _} the caller sees.

oneway(Pid, Function, Args, Timeout)

-spec oneway(pid(), binary(), [term()], pos_integer() | infinity) -> ok | {error, term()}.

Sends a one-way call; the server never answers.

start(Opts)

-spec start(options()) -> gen_server:start_ret().

Connects to the server without linking — for owners that monitor instead, such as pool workers started by a pool library.

start_link(Opts)

-spec start_link(options()) -> gen_server:start_ret().

Connects to the server and links the client to the caller; fails if the connection cannot be made.

stop(Pid)

-spec stop(pid()) -> ok.

Closes the connection; outstanding calls fail with {error, closed}.