2Sjch8AT
I have a GenServer which is using an array of other GenServer to fullfil its jobs, each of them being connected to different channels for sending data. The first GenServer is acting like a dispatcher. When a call on the first GenServer is invoked, one of the GenServer in the array is chosen and a call is performed on it.
I would like the GenServer (dispatcher) to be asynchronous: I don’t want to block while the data is sent to one of the GenServer contained in the array. But I would also ilke to check for errors, so using GenServer.cast is not an option.
What options do I have? Does it make sense to use spawn and GenServer.call for each incoming request coming to the dispatcher?
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication):
toke...
New
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New
** (ArgumentError) expected :max_attempts to be a positive integer, got: {:@, [line: 10, column: 19], [{:max_attempts, [line: 10, column:...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex










Showing Posts 1 to 4- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
amikhailov
Erlang
rpcimplements asynchronous calls exactly like this: otp/lib/kernel/src/rpc.erl at 613b5f890a5bc13aaf64cc31b535262a40eba721 · erlang/otp · GitHubSo yes, I think it’s the way to go.
peerreynders
That doesn’t make the dispatcher asynchronous - and this tactic is largely a defensive move by a client process forced to make a synchronous call when it doesn’t want to be blocked.
But not wanting to be blocked the client process still has to:
Given that you are implementing the dispatcher you might as well cut out the “proxy-process”:
cast/2the request to the dispatcher (include a reference fromKernel.make_ref/0in the request that the dispatcher can return in the response information to make it easier to correlate a response to a request).Process.monitor/2the dispatcher.:DOWN(viahandle_info/2) message with the dispatcher-monitor-reference and dispatcher PID, inspect the reason:noproc- there is no process withpid:noconnection- can’t reach specified node:normal- no worries, sent result is still in the queue (provided a result was sent)cast/2the response information (including the correlation reference) back to the client process.Process.demonitor/2the dispatch-monitor-reference (specifying[:flush]foroptsto purge the:DOWNmessage that could still be in the message queue) and then process the response information.See also: The need for monitoring
2Sjch8AT
Could you explain to me why?
Thanks for your detailed answer.
peerreynders
The intent of
call/3is to implement a synchronous protocol on top of a native asynchronous one.callboils down to the client sending a request and then blocking until a reply for that exact request arrives - ignoring any other messages that may arrive in the meantime.Now typically the server processes the request immediately in
handle_call/3and responds with a:reply.So the intent behind
call/handle_callis to implement a synchronous protocol.Now the server has some wiggleroom as it can finish
handle_callwith:noreplyto delay emitting a reply until later withreply/2but that doesn’t change the synchronous client experience (the server might do this to stop the same client from sending additional requests).The “spawn to call” tactic is used as a countermeasure by a client process which doesn’t wish to have the “synchronous experience” that
callenforces.Using “spawn to call” within the “service” (rather than on the client-side) may give the client process the illusion of asynchronous communication (while still leaving the burden of setting up the monitor and dealing with monitor messages) - but
callstill implements a synchronous protocol; for what purpose?(My guess is that the dispatcher core has been designed/written in terms of
handle_callwhich means that the dispatcher implementation is in fact synchronous. Such an implementation could be, not necessarily, but quite possibly blocked while processing a single request rather than servicing other requests asynchronously.)If the dispatcher is asynchronous and the clients need to deal with it asynchronously then simply have the dispatcher serve/implement
cast/handle_castinstead (while the dispatcher casts its reply back to the client) to fully reveal the dispatcher’s asynchronous nature.