Tasks and Agents
| Task.async await | |
| Agent state | |
| Update simply | |
| Task vs GenServer vs Agent |
Task.async await
A Task runs one function in the background while the caller keeps working. The async call returns a task struct at once, and await blocks until the result arrives. This pair fits single computations whose answer the caller needs later.
task = Task.async(fn -> Enum.sum([1, 2, 3]) end)
IO.inspect(Task.await(task))
6
Agent state
An Agent is a tiny process wrapping one value with get and update helpers. The start_link call boots it with the function return as the initial state. Reading never touches the value directly: a function receives the state and returns the part to expose.
{:ok, agent} = Agent.start_link(fn -> 0 end)
IO.inspect(Agent.get(agent, fn n -> n end))
0
Update simply
The update call transforms the stored value with a function and returns the atom ok. Each update runs inside the agent, so concurrent callers cannot interleave and lose changes. Reading back afterwards shows the new value.
Agent.update(agent, fn n -> n + 1 end)
IO.inspect(Agent.get(agent, fn n -> n end))
1
Task vs GenServer vs Agent
Pick the smallest tool that fits the job. Tasks handle one finished computation with a clear result. Agents guard plain shared state behind two functions. GenServers model long lived servers with custom messages and richer lifecycles.
# one finished job: Task
# shared counter: Agent
# custom messages and state: GenServer
Next: OTP applications
Article author: Arthur Isaev