AgentMap v1.1.0 AgentMap.Utils

Link to this section Summary

Functions

Returns property with given key

Returns property with given key or default

Wraps fun in a try…catch block before applying args

Executes safe_apply(fun, args) in a separate Task. If call takes too long — stops its execution

Stores property in a process dictionary of instance

Updates property stored in a process dictionary of instance

Link to this section Types

Link to this section Functions

Link to this function dec(am, key, opts \\ [step: 1, cast: true, initial: 0, !: :avg])
dec(am(), key(), keyword()) :: am()

Decrements value for key.

See inc/3.

Link to this function get_prop(am, key)
get_prop(am(), term()) :: term()

Returns property with given key.

Functions get_prop/2, upd_prop/3, set_prop/3 can be used inside callbacks.

Special properties

  • :size — current size (fast, but in some rare cases inaccurate upwards);

  • :real_size — current size (slower, but always accurate);

  • :max_processes — a limit for the number of processes allowed to spawn;

  • :processes — total number of processes being used (+1 for server itself).

Examples

iex> am = AgentMap.new()
iex> get_prop(am, :processes)
1
iex> get_prop(am, :max_processes)
5000
iex> am
...> |> sleep(:a, 10)
...> |> sleep(:b, 100)
...> |> get_prop(:processes)
3
#
iex> sleep(50)
iex> get_prop(am, :processes)
2
#
iex> sleep(200)
iex> get_prop(am, :processes)
1

#

iex> am = AgentMap.new()
iex> get_prop(am, :size)
0
iex> am
...> |> sleep(:a, 10)
...> |> sleep(:b, 50)
...> |> put(:b, 42)
...>
iex> get_prop(am, :size)       # size calculation is inaccurate, but fast
2
iex> get_prop(am, :real_size)  # that's better
0
iex> sleep(50)
iex> get_prop(am, :size)       # worker for :a just died
1
iex> get_prop(am, :real_size)
0
iex> sleep(40)                 # worker for :b just died
iex> get_prop(am, :size)
1
iex> get_prop(am, :real_size)
1
Link to this function get_prop(am, key, default)
This function is deprecated. Use get_prop/3 instead.

Returns property with given key or default.

Link to this function inc(am, key, opts \\ [step: 1, initial: 0, !: :avg, cast: true])
inc(am(), key(), keyword()) :: am()

Increments value with given key.

By default, returns without waiting for the actual increment.

Raises an ArithmeticError if current value associated with key is not a number.

Options

  • step: number, 1 — increment step;

  • initial: number, 0 — initial value;

  • initial: false — to raise KeyError on server if value does not exist;

  • cast: false — to return only after the increment;

  • !: priority, :avg;

  • :timeout, 5000.

Examples

iex> am = AgentMap.new(a: 1.5)
iex> am
...> |> inc(:a, step: 1.5)
...> |> inc(:b)
...> |> get(:a)
3.0
iex> get(am, :b)
1

iex> AgentMap.new()
...> |> sleep(:a, 20)
...> |> put(:a, 1)               # 1
...> |> cast(:a, fn 2 -> 3 end)  # : ↱ 3
...> |> inc(:a, !: :max)         # ↳ 2 :
...> |> get(:a)                  #     ↳ 4
3
Link to this function safe_apply(fun, args)

Wraps fun in a try…catch block before applying args.

Returns {:ok, reply}, {:error, reason}, where reason is :badfun, :badarity, {exception, stacktrace} or {:exit, reason}.

Examples

iex> safe_apply(:notfun, [])
{:error, :badfun}

iex> safe_apply(fn -> 1 end, [:extra_arg])
{:error, :badarity}

iex> fun = fn -> exit :reason end
iex> safe_apply(fun, [])
{:error, {:exit, :reason}}

iex> {:error, {e, _stacktrace}} =
...>   safe_apply(fn -> raise "oops" end, [])
iex> e
%RuntimeError{message: "oops"}

iex> safe_apply(fn -> 1 end, [])
{:ok, 1}
Link to this function safe_apply(fun, args, timeout)

Executes safe_apply(fun, args) in a separate Task. If call takes too long — stops its execution.

Returns {:ok, reply}, {:error, reason}, where reason is :badfun, :badarity, {exception, stacktrace}, {:exit, reason} or :timeout.

Examples

iex> fun = fn -> sleep(:infinity) end
iex> safe_apply(fun, [], 20)
{:error, :timeout}

iex> fun = fn -> sleep(10); 42 end
iex> safe_apply(fun, [], 20)
{:ok, 42}
Link to this function set_prop(am, key, value)
set_prop(am(), term(), term()) :: am()

Stores property in a process dictionary of instance.

See get_prop/3, upd_prop/4.

Examples

iex> am = AgentMap.new()
iex> am
...> |> set_prop(:key, 42)
...> |> get_prop(:key)
42

iex> am = AgentMap.new()
iex> get_prop(am, :bar)
nil
iex> get_prop(am, :bar, :baz)
:baz
iex> get_prop(am, :max_processes)
5000

Functions get_prop/2, upd_prop/3, set_prop/3 can be used inside callbacks:

iex> am = AgentMap.new()
iex> am
...> |> get(:a, fn _ -> set_prop(am, :foo, :bar) end)
...> |> get(:b, fn _ -> get_prop(am, :foo) end)
:bar
Link to this function sleep(am, key, t, opts \\ [!: {:max, +2}, cast: true])
sleep(am(), key(), pos_integer() | :infinity, keyword()) :: am()

Sleeps the given key for t ms.

Returns without waiting for the actual sleep to happen.

Options

  • cast: false — to return after the actual sleep;

  • !: priority, {:max, +2} — to postpone sleep until calls with a higher priority are executed.

Link to this function upd_prop(am, key, fun, opts \\ [cast: true])

Updates property stored in a process dictionary of instance.

Underneath, GenServer.cast/2 is used.

See get_prop/3, set_prop/3.

Options

  • cast: false — to wait for the actual update to occur.

Examples

iex> AgentMap.new()
...> |> set_prop(:key, 42)
...> |> upd_prop(:key, fn 42 -> 24 end)
...> |> get_prop(:key)
24