Quick question re: GenServer

Hi, I’m fairly new to Elixir and I’m learning about GenServer now. I am trying to do an asynchronous handle_call function where I spawn a process and immediately return a {:noreply, nil} tuple. Once the process is finished I’m calling the Genserver.reply/2 function.

I noticed that when I add a Process.sleep/1 before the Genserver.reply function, my iex console hangs for the 2 seconds instead of allowing me to continue firing events. Is that the way it’s supposed to work? and if so, why is this?

Here’s the code snippet

def handle_call({:get, file_path}, caller, state) do
  spawn(fn ->
    data = 
      case File.read(file_path) do
        {:ok, content} -> :erlang.binary_to_term(content)
        _ -> nil
      end

    Process.sleep(1000)
    GenServer.reply(caller, data)
  end)
  
  {:noreply, state}
end

Basically the caller process stops until the GenServer.reply/2 function is called.

Thanks

When you call a gen_server you wait for the reply, so if you add a delay before the response is sent you will wait the duration of that response.

Sending the reply from another process means the gen_server is ready to process further messages, but the original caller is still blocked.

6 Likes

Got it! That makes total sense.

Thank you

1 Like

@albertosh if you want to achieve non blocking asynchronous call you can also checkout Tasks

1 Like

Just a FYI, @LostKobrakai provided a clear explanation of what a task should be used for, in a question I asked earlier Tasks vs GenServer