vitorfam
Is it recommended to create a GenServer to make gRPC calls?
In my application, I need to make a lot of gRPC calls to a Python server. Is it recommended to create a GenServer to make those calls?
I’m trying to do the following:
defmodule MyApp.ClassifierServer do
use GenServer
alias MyApp.ClassifierImpl
@name __MODULE__
def start_link(_) do
classifier_host = Application.get_env(:myapp, MyApp.ClassifierServer)[:hostname]
{:ok, channel} = GRPC.Stub.connect(classifier_host)
GenServer.start_link(@name, channel, name: @name)
end
def init(channel) do
# Fazer uma verificação do status do serviço.
IO.puts("Starting channel to Classifier Server")
{:ok, channel}
end
def handle_call({:classify, params}, _from, channel) do
case ClassifierImpl.classify(params, channel) do
{:ok, response} ->
{:reply, response, channel}
{:error, error_message} ->
{:reply, error_message, channel}
end
end
end
When I start my application, I get the following message:
[error] Unexpected event in state :connected of type :info:
{:timeout, #Reference<0.3273821823.2036334600.82725>, {:cow_http2_machine, :settings_timeout}}
{:state, #PID<0.604.0>, {:up, #Reference<0.3273821823.2036334600.82721>}, 'localhost', 50051, "http", 'localhost', 50051, [], %{protocols: [:http2], retry: 100, retry_fun: &GRPC.Adapter.Gun.retry_fun/2, tcp_opts: [nodelay: true], transport: :tcp}, #Reference<0.3273821823.2036334600.82726>, #Port<0.23>, :gun_tcp, true, {:tcp, :tcp_closed, :tcp_error}, :gun_http2, {:http2_state, #Port<0.23>, :gun_tcp, %{initial_connection_window_size: 8000000, initial_stream_window_size: 8000000}, [:gun_data_h], "", :connected, {:http2_machine, :client, %{initial_connection_window_size: 8000000, initial_stream_window_size: 8000000}, :normal, :undefined, #Reference<0.3273821823.2036334600.82725>, %{initial_window_size: 65535}, %{initial_window_size: 8000000}, %{initial_window_size: 4194304, max_frame_size: 4194304, max_header_list_size: 8192}, 4194304, 8000000, 1, 0, [], [], [], {:state, 0, 4096, 4096, []}, {:state, 0, 4096, 4096, []}}, %{}, %{}}, :gun_default_event_h, :undefined}
and the supervisor tries to restart the server every time I get this error.
Most Liked
tristan
It probably depends on the grpc library. Looking at your example code I would not suggest the same when using grpcbox (https://github.com/tsloughter/grpcbox). grpcbox has client side load balancing and handles channels/subchannels for you, so keeping a connection in a genserver state is not the recommended way to go.
And while grpcbox is Erlang, I know there are production users who are using it from Elixir.
axelson
Some good reading on this topic if you haven’t already read it is https://www.theerlangelist.com/article/spawn_or_not








