LazyAgent v1.1.0 LazyAgent View Source

LazyAgent

Hex.pm Build Docs Build Status

LazyAgent wraps Elixir’s Agent library to allow delayed execution of the initial state generator function until the first time the Agent process is accessed.

It is intended to be used in test environments of applications with agents that have initialization functions that take hundreds of milliseconds or more to execute. When developing and running a subset of the test suite, these type of agents can significantly increase the time it takes to run tests, which slows down development. Using LazyAgent allows execution of only the initialization functions necessary to run the test subset.

Installation

Install LazyAgent by adding lazy_agent to your list of dependencies in mix.exs:

def deps do
  [
    {:lazy_agent, "~> 0.1.0"}
  ]
end

Configuration

To enable or disable LazyAgent, add the following to an environment configuration file:

use Mix.Config

config :lazy_agent, enabled?: true

LazyAgent supports Confex-style configs, so you can rely on environment variables:

use Mix.Config

config :lazy_agent,
  enabled?: {:system, :boolean, "ENABLE_LAZY_AGENT", true}

Usage

Currently, LazyAgent supports the lazy equivalents of:

iex> {:ok, pid} = LazyAgent.start_link(fn -> 42 end)
iex> LazyAgent.get(pid, fn state -> state end)
42

iex> LazyAgent.start_link(fn -> 42 end, name: :lazy)
iex> LazyAgent.update(:lazy, fn state -> state + 5 end)
:ok
iex> LazyAgent.get(:lazy, fn state -> state end)
47

iex> {:ok, pid} = LazyAgent.start(fn -> 42 end)
iex> LazyAgent.get_and_update(pid, fn state -> {state, state + 5} end)
42
iex> LazyAgent.get(pid, fn state -> state end)
47
iex> LazyAgent.stop(pid)
:ok

Link to this section Summary

Functions

Gets an agent value via the given anonymous function, similar to Agent.get/3

Gets and updates the agent state in one operation via the given anonymous function, similar to Agent.get_and_update/3

Starts an agent without links, initializing the state with the given function, similar to Agent.start/2

Starts an agent linked to the current process with the given function, similar to Agent.start_link/2

Synchronously stops the agent with the given reason, similar to Agent.stop/3

Updates the agent state via the given anonymous function, similar to Agent.update/3

Link to this section Types

Link to this type start_fun() View Source
start_fun() :: (() -> state())
Link to this type t() View Source
t() :: %LazyAgent{start_fun: start_fun(), started?: boolean(), state: state()}

Link to this section Functions

Link to this function get(agent, fun, timeout \\ 5000) View Source
get(agent(), (state() -> term()), timeout()) :: term()

Gets an agent value via the given anonymous function, similar to Agent.get/3.

The function fun is sent to the agent which invokes the function passing the agent state. The result of the function invocation is returned from this function.

If the agent’s state was not previously initialized, it will be initialized exactly once for the first call to LazyAgent.get/3.

Examples

iex> {:ok, pid} = LazyAgent.start_link(fn -> 42 end)
iex> LazyAgent.get(pid, fn state -> state end)
42

iex> LazyAgent.start_link(fn -> 42 end, name: :lazy)
iex> LazyAgent.get(:lazy, fn state -> state end)
42
Link to this function get_and_update(agent, fun, timeout \\ 5000) View Source
get_and_update(Agent.agent(), (state() -> {term(), state()}), timeout()) ::
  term()

Gets and updates the agent state in one operation via the given anonymous function, similar to Agent.get_and_update/3.

The function fun must return a tuple with two elements, the first being the value to return and the second being the new state of the agent.

If the agent’s state was not previously initialized, it will be initialized exactly once for the first call to LazyAgent.update/3.

Examples

iex> {:ok, pid} = LazyAgent.start_link(fn -> 42 end)
iex> LazyAgent.get_and_update(pid, fn state -> {state, state + 5} end)
42
iex> LazyAgent.get(pid, fn state -> state end)
47

Starts an agent without links, initializing the state with the given function, similar to Agent.start/2.

Link to this function start_link(fun, options \\ []) View Source

Starts an agent linked to the current process with the given function, similar to Agent.start_link/2.

Link to this function stop(agent, reason \\ :normal, timeout \\ :infinity) View Source
stop(agent(), reason :: term(), timeout()) :: :ok

Synchronously stops the agent with the given reason, similar to Agent.stop/3.

Link to this function update(agent, fun, timeout \\ 5000) View Source
update(Agent.agent(), (state() -> state()), timeout()) :: term()

Updates the agent state via the given anonymous function, similar to Agent.update/3.

The return value of fun becomes the new state of the agent.

If the agent’s state was not previously initialized, it will be initialized exactly once for the first call to LazyAgent.update/3.

Examples

iex> {:ok, pid} = LazyAgent.start_link(fn -> 42 end)
iex> LazyAgent.update(pid, fn state -> state + 5 end)
:ok
iex> LazyAgent.get(pid, fn state -> state end)
47