SimpleAgent

SimpleAgent is a simplification/abstraction layer around the base Elixir Agent module.

Often times, Agents are used to store a simple value, such as an atom or an integer. This is used as a flag or a count which multiple processes can access/update. In these cases, the full Agent module is used with boilerplate closure code that is repetative, adds noise to the code, and can be eliminated. For example, to create an agent, update the value, then retrieve that code, you would run:

{:ok, agent} = Agent.start_link(fn -> nil end)
Agent.update(agent, fn _ -> :completed end)
completed = Agent.get(agent, fn val -> val != nil end)

SimpleAgent boils these calls down to a more readable:

agent = SimpleAgent.start!
SimpleAgent.update! agent, :completed
completed = SimpleAgent.equals? agent, :completed

For Integer manipulation, SimpleAgent takes this code:

{:ok, agent} = Agent.start_link(fn -> 0 end)
IO.puts Agent.get_and_update(fn val -> {val + 1, val + 1} end)
IO.puts Agent.get_and_update(fn val -> {val - 1, val - 1} end)
IO.puts Agent.get_and_update(fn val -> {val + 1, val + 1} end)
IO.puts Agent.get_and_update(fn val -> {val + 1, val + 1} end)

and boils it down to the more readable:

agent = SimpleAgent.start! 0
IO.puts SimpleAgent.increment! agent
IO.puts SimpleAgent.decrement! agent
IO.puts SimpleAgent.increment! agent
IO.puts SimpleAgent.increment! agent

SimpleAgent is very useful in testing. For example:

test "foo calls bar 3 times" do
  bar_call_agent = SimpleAgent.start! 0
  :meck.new(Bar)
  :meck.expect(Bar, :bar, fn -> SimpleAgent.increment!(bar_call_agent) end)
  Foo.foo()
  assert SimpleAgent.get?(bar_call_agent) == 3
end

Why only simple types?

When a complex state such as a map or a dict is in use, the correct way to manipulate the complex state is in the Agent server via a closure. This prevents the entire state from being copied from the Agent Server to the Client (see the Agent docs for more information on this). For states with these complex types, you should use the full Agent module. SimpleAgent is for those cases where the “entire state” is a single simple value.

Features:

Source

Summary

clear(agent)

Resets the current state to nil

decrement!(agent)

Decreases the value of the current state by 1. Raises error if current state is not an integer

equals?(agent, val)

Returns true or false if the current state of the specified agent is the specified value

get!(agent)

Returns the current state of the agent. If the agent has an invalid type, raises an exception

increment!(agent)

Increases the value of the current state by 1. Raises error if current state is not an integer

nil?(agent)

Returns true or false if the current state is nil

start!(initial_state \\ nil, options \\ [])

Starts an agent with the specified initial value, or nil by default. Second optional parameter is the standard GenServer options list

update!(agent, val)

Updates the state to the new value. Returns the new value

Types

valid_types :: Atom | Integer | boolean | String.t | nil

Functions

clear(agent)

Specs:

Resets the current state to nil

Source
decrement!(agent)

Specs:

  • decrement!(agent) :: Integer

Decreases the value of the current state by 1. Raises error if current state is not an integer

Source
equals?(agent, val)

Specs:

Returns true or false if the current state of the specified agent is the specified value

Source
get!(agent)

Specs:

Returns the current state of the agent. If the agent has an invalid type, raises an exception

Source
increment!(agent)

Specs:

  • increment!(agent) :: Integer

Increases the value of the current state by 1. Raises error if current state is not an integer

Source
nil?(agent)

Specs:

Returns true or false if the current state is nil

Source
start!(initial_state \\ nil, options \\ [])

Specs:

Starts an agent with the specified initial value, or nil by default. Second optional parameter is the standard GenServer options list.

Return values

Returns the pid of the server to be used in subsequent calls to other SimpleAgent functions.

Source
update!(agent, val)

Specs:

Updates the state to the new value. Returns the new value.

Source