tomthestorm
Hi, I try understand GenServer .
Why GenServer.call is synchronous ? I want to get, in asynchronous way, information about state of the pid, but I can’t.
For example if I send 1000 of GenServer.call(pid,:get) via :
[ Task.await(Task.async(fn → Genserver.call(pid,:get) end)) , [ Task.await(Task.async(fn → Genserver.call(pid,:get) end)) , … , … ]
when I get the last one I have to wait 999 times.
Maybe it is stupid question , but for me GenServer.call should be asynchronous because we want read state and GenServer.cast should be synchronous cause we modify the state (and we should lock state during modification) .
But the situation is opposite and I don’t understand why .
Thanks in advance for answer .
Trending in Questions
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
New
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
Other Trending Topics
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
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #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
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
sztosz
Cast and call are not about whether we read or modify the state, but do we wan’t to wait for the response, and do nothing or are we not going to wait for the response (we don’t care about the response at all).
Cast and call both can modify state.
Call is synchronous by nature, because it hast to send a response for which calling process await.
And beside that messages in GenServer are read sequentially IIRC, so any computation done based on message are done sequentially too.
benwilson512
There are two minor misconceptions here:
callvscastis not about read vs write. You can (and usually should) modify viacall, and you often usecallto read too. Call vs cast is literally about whether you as the client want to communicate async vs sync.This becomes clearer if you think about the mechanism of communication: message passing. All message passing is async, so if you send a message to the genserver to read OR write and you want to know the result, the only way you can do so is to wait around for a reply message from the genserver. This is exactly what
calldoes. If you want to write and you don’t care about the result, or if you want to tell the genserver to send you a reply and you’ll look at it later, you can considercast.The second misconception is that the genserver is some state that can be read directly by the client. As noted, all communication between processes is via message passing, and so if clients want to read a genserver, the genserver needs to send them a message. Genservers, like all processes, are single threaded, and so the message sending happens one after the next.
peerreynders
For some background this topic may be of some interest:
This may already be an indication that you are solving your problem in a less than optimal way in a process-oriented environment (there simply isn’t enough detail to know whether this is in fact true).
More often than not process state exists to enable the process to enact some sort of protocol in concert with other processes rather than the process simply acting as a container-of-state to be queried.
To a certain degree this has been a problem in some object-oriented designs and can be even more a problem with process-oriented solutions.
Some of my posts around “Tell, don’t Ask”:
You wouldn’t write code like that anyway. At the very least you would organize it more like:
or
The idea being that you first launch all the tasks and only then you start waiting on them (in this particular case it wouldn’t make much of a difference as you are waiting on the same process anyway).
And ideally you would be using
Task.Supervisor.async_stream/6anyway, as that gives you better control of the level of concurrency that may be reasonable under the circumstances.tomthestorm
Thanks for all answers.
So is there any possibility to get the state (if the process hold the state) from the process in asynchronous way ?
Anyway thanks for idea ““Tell, don’t Ask” , I’ll try change my thinking.
benwilson512
@tomthestorm if you mean async with respect to the client, the client can simply do
current_process = self(); GenServer.cast(pid, {:give_me_state, current_process})and then the genserver can message the current process with its state.If what you’re looking for is some kind of key value store that could be accessed concurrently by many processes, then that’s what an
:etstable provides.benwilson512
It may also help if you were to sketch out what kind of client side code you’re expecting here. It sort of sounds like you’re wondering if there is a way to get the Processes’s state without actually sending it a message, and no that is not possible. A GenServer is just a loop with a receive block, and if you want it to do something the only want to ask it is via a message.
sribe
What do you mean get it in an asynchronous way? How do you want the caller to receive the value?
peerreynders
Example: stack server with an asynchronous “pop” and a proxy server which turns it into a synchronous “pop”.
OvermindDL1
I wish instead of just
GenServer.callandGenServer.castwe also had aGenServer.asyncor something where it returns an opaque type that you can then laterGenServer.awaiton to get the result. It would be really easy to make and would make interleaving work easier, but otherwise it would just be a wrapper around theGenServer.callprotocol (async would send a message with a ref and pid, return that ref, then await would take that ref and receive on it to get the output). You can build that yourself with cast, but it would be nice to wrap the call protocol.peerreynders
Given the blocking nature, I don’t think the
awaitconcept is really appropriate inside a typicalGenServer. What you want is a way to continue processing once the result becomes available - and there really isn’t that much ceremony involved in rigging something up.