Lockstep.Agent (Lockstep v0.1.0)

Copy Markdown View Source

Controller-aware Agent -- mirrors the OTP Agent API but every get/update/cast/get_and_update is a Lockstep.GenServer.call (or cast) and therefore a sync point.

Without this wrapper, Agent.get/3-4 etc. go through vanilla :gen_server.call, bypassing Lockstep's controller. That hides any race between an Agent.get (when the user does work outside the agent based on the value, then calls back in) and a concurrent Agent.update.

A typical example: an LRU cache that does :ets.lookup directly then calls Agent.get(...) -- a delete in between corrupts the LRU's TTL table. Lockstep can find that race only if both the ETS calls AND the Agent calls are sync points.

Summary

Functions

Fire-and-forget update.

Apply fun to the agent's state and return the result.

Apply module.fun([state | args]) and return the result.

Atomically get and update via fun.(state) -> {result, new_state}.

Unlinked variant of start_link/1.

Start an agent linked to the calling process. fun is invoked to produce the initial state.

Start an agent with options (name: for atom registration).

Start an agent invoking apply(module, fun, args) to produce initial state.

Update the state via fun.(state).

Update via module.fun([state | args]).

Functions

cast(agent, fun)

Fire-and-forget update.

cast(agent, module, fun, args)

get(agent, fun, timeout \\ 5000)

Apply fun to the agent's state and return the result.

get(agent, module, fun, args, timeout \\ 5000)

Apply module.fun([state | args]) and return the result.

get_and_update(agent, fun, timeout \\ 5000)

Atomically get and update via fun.(state) -> {result, new_state}.

get_and_update(agent, module, fun, args, timeout \\ 5000)

start(fun)

Unlinked variant of start_link/1.

start(fun, opts)

start(module, fun, args)

start(module, fun, args, opts)

start_link(fun)

Start an agent linked to the calling process. fun is invoked to produce the initial state.

start_link(fun, opts)

Start an agent with options (name: for atom registration).

start_link(module, fun, args)

Start an agent invoking apply(module, fun, args) to produce initial state.

start_link(module, fun, args, opts)

stop(agent, reason \\ :normal, timeout \\ :infinity)

Stop the agent.

update(agent, fun, timeout \\ 5000)

Update the state via fun.(state).

update(agent, module, fun, args, timeout \\ 5000)

Update via module.fun([state | args]).