srowley
Why does starting an Agent require a function?
Why do Agent.start_link/2, get/3 and update/3 take a function to set/get state? Why not just pass/retrieve the state directly, i.e., if I want the state to be 42, just let me pass 42 instead of fn -> 42 end?
This isn’t a complaint as I am sure there is a good (maybe obvious) reason for this, this question is really just a request for a learning opportunity for me if anyone is willing to explain.
Most Liked
Nicd
I suppose it’s so that if the agent has heavy/long initialisation/update work, it is then run in the agent and not the calling process, and the calling process can set a timeout for the work which crashes the agent.
As for the update case specifically, if the workflow was: 1) get value from agent, 2) update value locally, 3) send updated value to agent, then there is a risk of race conditions. When the update is done in the agent process, access is serialised automatically.
LostKobrakai
If you’d pass the initial state after starting the Agent process using plain messages you’ll be open to race conditions. Meaning updates might be processed before your initial state is received and applied.
dimitarvp
Two reasons:
-
Making sure the initial value gets extracted in the
Agent processand not the one you are creating it in. If that analogy is easier for you, think of it in terms of multi-threading: you’re spawning thread B from thread A and want thread B to evaluate the initial value of the held state so as thread A is not blocked evaluating it. -
Lazy loading. You might want an
Agentto actually fetch stuff from database, caches, 3rd party APIs, configuration or discovery providers etc. This circles back to the reasoning that if the initial state is expensive to compute then you’d block your original process and you don’t want that.
As for “why don’t they have an alternative API for people who know what they are doing and want to supply a static value” I’d say that it’s better safe then sorry. Writing fn -> 42 end is not much harder than 42 and you gain 100% confidence that your Agent's state will never be evaluated in the context of the caller, only in the callee (the Agent itself).
srowley
Yep, now I get it - thanks everyone!







