We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
`GenServer.call/3` timeout does not cancel work
almirsarajcic
Treat the third argument to GenServer.call/3 as a caller deadline, not a cancellation mechanism. When the deadline expires, the call exits the caller while the GenServer continues processing the request.
defmodule PricingClient do
def quote(server, cart_id) do
GenServer.call(server, {:quote, cart_id}, 2_000)
catch
:exit, {:timeout, {GenServer, :call, _args}} ->
{:error, :timeout}
end
end
GenServer.call/2 uses a default timeout of 5,000 milliseconds. GenServer.call/3 accepts a positive integer in milliseconds or :infinity.
A timeout is an exit, not an {:error, :timeout} return value. Catch the full {:timeout, {GenServer, :call, args}} shape only at a boundary where a timeout is an expected result, as above. Other exits—such as calling a missing server—still propagate instead of being mislabeled as timeouts.
The server receives no cancellation signal when the caller stops waiting. Its handle_call/3 callback keeps running, including any external requests or database writes it already started. Because a GenServer handles callbacks sequentially, that work can also keep later messages waiting. Use a task or an asynchronous workflow when the server must remain responsive during slow work.
On OTP 24 and later, gen_server.call uses process aliases, so a reply sent after the timeout is discarded instead of entering the caller’s mailbox. Older OTP releases could leave a {reference, reply} message behind. This prevents mailbox garbage on current OTP, but it still does not stop the server’s work.
GenServer.call/3 also does not link the caller to the server or make the timeout part of a supervision tree. Its guarantee is narrower: wait for a reply up to the configured deadline, then exit the caller.
copied to clipboard