larshei

larshei

GenServer/Process to receive gRPC Stream Data?

Hey everyone,

I want to receive data from a gRPC stream.

So far, I only wrote functions, played around in iex and was able to receive and decode data. It is time to “applicationify” that previous work and add lifecycle management/processes. But somehow, the gRPC behaviour seems different in GenServer compared to the iex session? :thinking:

I found a similar post in the forum: Elixir-grpc can't receive stream response. Unexpected when waiting for headers- which ends on

Looks like GRPC.Stub.recv can’t be used in GenServers :thinking:

But that seems weird to me.

Setup in iex

Basically, the stripped down version looks something like this:

  # wrapper around GRPC.Stub.connect() that handles auth etc
  {:ok, channel} = SalesforceEvents.Grpc.connect()

  grpc_stream = Eventbus.V1.PubSub.Stub.subscribe(channel)
  GRPC.Stub.send_request(grpc_stream, Messages.request_data())
  {:ok, data_stream} = GRPC.Stub.recv(grpc_stream, timeout: 60_000)
  
  Enum.each(data_stream, &IO.inspect/1)
# shell blocks, protobuf-decoded data is printed as it comes in

Setup with GenServer

Same as above, but in a GenServer.

Handling incoming stream data with Enum.each is spawned as a separate process:

@impl true
def init(args) do
  {:ok, channel} = SalesforceEvents.Grpc.connect() 

  grpc_stream = Eventbus.V1.PubSub.Stub.subscribe(channel)
  GRPC.Stub.send_request(grpc_stream, Messages.request_data())
  {:ok, data_stream} = GRPC.Stub.recv(grpc_stream, timeout: 60_000)

  receiver_process =
    spawn_link(fn -> Enum.each(data_stream, &IO.inspect/1) end)

  state = %{
    channel: channel,
    grpc_stream: grpc_stream,
    data_stream: data_stream,
    receiver_process: receiver_process
  }

  {:ok, state}
end

def handle_info(info, state) do
   Logger.debug(inspect info)
  {:noreply, state}
end

Expected Behaviour

Received gRPC messages are still printed to the console

Actual Behaviour

Instead of the messages being printed, the handle_info receives messages like the following:

08:45:41.824 [debug] {:gun_data, pid<0.339.0>, reference<0.2404288951.1709178882.257606>, :nofin, <<0, 0, 0, 1, 198, 10, 145, 3, …>>}

Why does this behave differently (nothing is printed, messages are not decoded)?
How can I receive data from a gRPC stream within a process getting results similar to what I had in iex?

First Post!

larshei

larshei

Interestingly it works when I move

  grpc_stream = Eventbus.V1.PubSub.Stub.subscribe(channel)
  GRPC.Stub.send_request(grpc_stream, Messages.request_data())
  {:ok, data_stream} = GRPC.Stub.recv(grpc_stream, timeout: 60_000)

into the spawned process.

Do the subscribe and recv functions need to be called from the same process?

Why is that?

Where Next?

Popular in Questions Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31586 112
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement