livery_grpc_client (livery_grpc v0.1.1)

View Source

gRPC client over the livery h2 client.

Open a connection with connect/2,3, then call methods. A call reads like erpc: hand it a method descriptor and a request message, get a reply back.

{ok, Conn} = livery_grpc_client:connect("localhost", 50051),
{ok, M} = livery_grpc_client:method(helloworld_pb, 'Greeter', 'SayHello'),
{ok, #{message := Msg}} = livery_grpc_client:call(Conn, M, #{name => <<"ada">>}),
ok = livery_grpc_client:close(Conn).

The connection's events are delivered to the process that called connect/2,3, so make calls from that same process. Calls are synchronous: each one drives its stream to completion before returning.

call/3,4 handles unary ({ok, Reply}) and server-streaming ({ok, [Reply]}). For client-streaming use client_stream/3,4; for bidirectional (or fine-grained control) use open/2,3 then send/2, send_end/1, and recv/1,2.

Calls compose through an interceptor stack, the outbound twin of livery's server middleware (Tower layers on the BEAM). Pass interceptors to connect/3 (per connection) or to a call's options (per call); each entry is {Module, State} or fun((Request, Next) -> Result), the same shape as livery_client layers. before/1, after_response/1, and wrap/1 build common ones.

Summary

Functions

Lift a result transformer (applied on success) into an interceptor.

Lift a request transformer into an interceptor.

call/4 with default options.

Invoke a method. Unary returns {ok, Reply}; server-streaming returns {ok, [Reply]}. A non-OK gRPC status is {error, {Status, Message}}.

Cancel a streaming call, resetting its stream (the server sees a disconnect). Use this to stop a stream early; unary calls are bounded by their deadline instead.

Client-streaming call: send all Requests, half-close, and return the single reply ({ok, Reply}) or the error status.

Close a connection.

Open an h2c connection to a gRPC server.

Open a connection. Opts: transport (tcp for h2c, the default, or ssl), authority (the :authority header, derived from host and port if absent), ssl_opts, timeout, and interceptors (a layer stack run around every unary and server-streaming call on this connection).

The request's call metadata (for use inside an interceptor).

Look up a method descriptor by proto module, service, and RPC name.

open/3 with default options.

Open a streaming call. Drive it with send/2, send_end/1 (half-close), and recv/1,2. Use this for bidirectional calls and for fine-grained client-streaming. The connection's events go to the calling process, so use the handle from there.

recv/2 with the default timeout.

Receive the next reply on a streaming call: {ok, Reply, Call}, {eof, Outcome, Call} once the server has finished (carrying the gRPC status), or {error, Reason, Call}.

Send one request message on a streaming call.

Half-close the send side: no more requests will be sent.

Add or replace call metadata on a request (for use in a before).

Wrap a call to catch exceptions, mirroring livery_client:wrap/1.

Types

call_opts()

-type call_opts() ::
          #{timeout => timeout(),
            deadline => pos_integer(),
            metadata => [{binary(), binary()}],
            compression => livery_grpc_compression:algorithm(),
            interceptors => interceptors()}.

call_result()

-type call_result() ::
          {ok, map() | tuple()} |
          {ok, [map() | tuple()]} |
          {error, {livery_grpc_status:status(), binary()}} |
          {error, {livery_grpc_status:status(), binary(), Details :: binary()}} |
          {error, term()}.

client_call()

-opaque client_call()

conn()

-opaque conn()

grpc_request()

-type grpc_request() ::
          #{method := livery_grpc_service:method(),
            message := map() | tuple(),
            metadata := [{binary(), binary()}],
            opts := call_opts()}.

interceptor()

-type interceptor() :: {module(), term()} | fun((grpc_request(), next()) -> call_result()).

interceptors()

-type interceptors() :: [interceptor()].

next()

-type next() :: fun((grpc_request()) -> call_result()).

outcome()

-type outcome() ::
          ok |
          {livery_grpc_status:status(), binary()} |
          {livery_grpc_status:status(), binary(), binary()}.

Functions

after_response(Fun)

-spec after_response(fun((call_result()) -> call_result())) -> interceptor().

Lift a result transformer (applied on success) into an interceptor.

before(Fun)

-spec before(fun((grpc_request()) -> grpc_request())) -> interceptor().

Lift a request transformer into an interceptor.

call(Conn, Method, Request)

-spec call(conn(), livery_grpc_service:method(), map() | tuple()) -> call_result().

call/4 with default options.

call/4

-spec call(conn(), livery_grpc_service:method(), map() | tuple(), call_opts()) -> call_result().

Invoke a method. Unary returns {ok, Reply}; server-streaming returns {ok, [Reply]}. A non-OK gRPC status is {error, {Status, Message}}.

The call runs through the connection's interceptor stack (plus any per-call interceptors), the gRPC analogue of livery's server middleware and livery_client layers: each interceptor is call(Request, Next, State) and may rewrite the request, observe the result, or short-circuit, with errors threaded as values.

cancel/1

-spec cancel(client_call()) -> ok | {error, term()}.

Cancel a streaming call, resetting its stream (the server sees a disconnect). Use this to stop a stream early; unary calls are bounded by their deadline instead.

client_stream(Conn, Method, Requests)

-spec client_stream(conn(), livery_grpc_service:method(), [map() | tuple()]) -> call_result().

client_stream/4 with default options.

client_stream(Conn, Method, Requests, Opts)

-spec client_stream(conn(), livery_grpc_service:method(), [map() | tuple()], call_opts()) ->
                       call_result().

Client-streaming call: send all Requests, half-close, and return the single reply ({ok, Reply}) or the error status.

close/1

-spec close(conn()) -> ok.

Close a connection.

connect(Host, Port)

-spec connect(string(), inet:port_number()) -> {ok, conn()} | {error, term()}.

Open an h2c connection to a gRPC server.

connect(Host, Port, Opts)

-spec connect(string(), inet:port_number(), map()) -> {ok, conn()} | {error, term()}.

Open a connection. Opts: transport (tcp for h2c, the default, or ssl), authority (the :authority header, derived from host and port if absent), ssl_opts, timeout, and interceptors (a layer stack run around every unary and server-streaming call on this connection).

metadata/1

-spec metadata(grpc_request()) -> [{binary(), binary()}].

The request's call metadata (for use inside an interceptor).

method(Proto, Service, Name)

-spec method(module(), atom(), atom()) -> {ok, livery_grpc_service:method()} | error.

Look up a method descriptor by proto module, service, and RPC name.

open(Conn, Method)

-spec open(conn(), livery_grpc_service:method()) -> {ok, client_call()} | {error, term()}.

open/3 with default options.

open/3

-spec open(conn(), livery_grpc_service:method(), call_opts()) -> {ok, client_call()} | {error, term()}.

Open a streaming call. Drive it with send/2, send_end/1 (half-close), and recv/1,2. Use this for bidirectional calls and for fine-grained client-streaming. The connection's events go to the calling process, so use the handle from there.

recv(Call)

-spec recv(client_call()) ->
              {ok, map() | tuple(), client_call()} |
              {eof, outcome(), client_call()} |
              {error, term(), client_call()}.

recv/2 with the default timeout.

recv/2

-spec recv(client_call(), timeout()) ->
              {ok, map() | tuple(), client_call()} |
              {eof, outcome(), client_call()} |
              {error, term(), client_call()}.

Receive the next reply on a streaming call: {ok, Reply, Call}, {eof, Outcome, Call} once the server has finished (carrying the gRPC status), or {error, Reason, Call}.

send/2

-spec send(client_call(), map() | tuple()) -> ok | {error, term()}.

Send one request message on a streaming call.

send_end/1

-spec send_end(client_call()) -> ok | {error, term()}.

Half-close the send side: no more requests will be sent.

set_metadata(Md, Req)

-spec set_metadata([{binary(), binary()}], grpc_request()) -> grpc_request().

Add or replace call metadata on a request (for use in a before).

wrap(Fun)

-spec wrap(fun((throw | error | exit, term(), list()) -> call_result())) -> interceptor().

Wrap a call to catch exceptions, mirroring livery_client:wrap/1.