Packages
gRPC client implementation for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/grpc/client/stream.ex
defmodule GRPC.Client.Stream do
@moduledoc """
A struct that *streaming* clients get from rpc function calls and use to send further requests.
## Fields
* `:channel` - `GRPC.Channel`, the channel established by client
* `:payload` - data used by adapter in a request
* `:path` - the request path to sent
* `:marshal` - a function encoding the request
* `:unmarshal` - a function decoding the reply
* `:req_stream` - indicates if request is streaming
* `:res_stream` - indicates if reply is streaming
"""
@typep marshal :: (struct -> binary)
@typep unmarshal :: (binary -> struct)
@typep stream_payload :: any
@type t :: %__MODULE__{
channel: GRPC.Channel.t(),
service_name: String.t(),
method_name: String.t(),
grpc_type: atom,
rpc: tuple,
payload: stream_payload,
path: String.t(),
marshal: marshal | nil,
unmarshal: unmarshal | nil,
server_stream: boolean,
canceled: boolean,
__interface__: map
}
defstruct channel: nil,
service_name: nil,
method_name: nil,
grpc_type: nil,
rpc: nil,
payload: %{},
path: nil,
marshal: nil,
unmarshal: nil,
server_stream: nil,
# TODO: it's better to get canceled status from adapter
canceled: false,
__interface__: %{send_request: &__MODULE__.send_request/3, recv: &GRPC.Stub.do_recv/2}
@doc false
def put_payload(%{payload: payload} = stream, key, val) do
payload = if payload, do: payload, else: %{}
%{stream | payload: Map.put(payload, key, val)}
end
@doc false
@spec send_request(GRPC.Client.Stream.t(), struct, Keyword.t()) :: GRPC.Client.Stream.t()
def send_request(%{marshal: marshal, channel: channel} = stream, request, opts) do
message = marshal.(request)
send_end_stream = Keyword.get(opts, :end_stream, false)
channel.adapter.send_data(stream, message, send_end_stream: send_end_stream)
end
end