Agents
Understand agents as background processes in Elixir.
We'll cover the following
Introduction
An agent is a background process that maintains a state. We can access this state at different places within a process, within a node, or across multiple nodes. A function sets the initial state we pass when we start the agent.
We can interrogate the state using Agent.get
, passing it the agent descriptor and a function. The agent runs the function on its current state and returns the result.
We can also use Agent.update
to change the state held by an agent. As with the get
operator, we pass in a function. Unlike with get
, the function’s result becomes the new state.
Example
Here’s a bare-bones example. We start an agent whose state is the integer 0
. We then use the identity function, &(&1)
, to return that state. Calling Agent.update
with &(&1+1)
increments the state, as verified by a subsequent get
.
iex> { :ok, count } = Agent.start(fn -> 0 end)
{:ok, #PID<0.69.0>}
iex> Agent.get(count, &(&1))
0
iex> Agent.update(count, &(&1+1))
:ok
iex> Agent.update(count, &(&1+1))
:ok
iex> Agent.get(count, &(&1))
2
In the previous example, the variable count
holds the agent process’s PID. We can also give agents a local or global name and access them using this name. In this case, we exploit the fact that an uppercase bare word in Elixir is converted into an atom with the prefix Elixir.
, so when we say Sum
it’s actually the atom :Elixir.Sum
.
iex> Agent.start(fn -> 1 end, name: Sum)
{:ok, #PID<0.78.0>}
iex> Agent.get(Sum, &(&1))
1
iex> Agent.update(Sum, &(&1+99))
:ok
iex> Agent.get(Sum, &(&1))
100
The following example shows a more typical use. The Frequency
module maintains a list of word-frequency pairs in a map. The dictionary itself is stored in an agent named after the module.
This is all initialized with the start_link
function, which presumably is invoked during application initialization.
Get hands-on with 1400+ tech skills courses.