structured_io v1.5.0 StructuredIO.GenServerTransaction View Source
Implements transactional changes to GenServer state.
You can call transaction/3 directly, but this module is better incorporated
into a GenServer via the use directive. Doing so defines a public function
in your module according to the following options/0:
:function_name— the name of the function to be defined in your module; defaults totransaction:server_name— the name of the first parameter in the defined function; defaults toserver:commit_instruction— thecommit_instruction/0expected from anoperation/0passed to the function; defaults to:commit:append_to_doc— content to be appended to the defined function’s default@docattribute, such as example code:since— the version expression to be assigned to the defined function’s@sinceattribute
Examples
iex> defmodule Counter do
...> use GenServer
...> use StructuredIO.GenServerTransaction, server_name: "counter"
...>
...>
...> def start_link, do: GenServer.start_link(__MODULE__, 0)
...>
...>
...> def current(counter), do: GenServer.call(counter, :current)
...>
...>
...> def increment(counter), do: GenServer.call(counter, :increment)
...>
...>
...> def handle_call(:current, _from, current=state), do: {:reply, current, state}
...>
...>
...> def handle_call(:increment, _from, current=_state) do
...> new_state = current + 1
...> {:reply, current, new_state}
...> end
...>
...>
...> def init(argument) when is_integer(argument), do: {:ok, argument}
...> end
iex> {:ok,
...> counter} = Counter.start_link
iex> Counter.current counter
0
iex> Counter.increment counter
iex> Counter.current counter
1
iex> Counter.transaction counter,
...> fn c ->
...> 1 = Counter.current(c)
...>
...> Counter.increment c
...> 2 = Counter.current(c)
...>
...> {:commit, :this_is_a_success}
...> end
:this_is_a_success
iex> Counter.current counter
2
iex> Counter.transaction counter,
...> fn c ->
...> 2 = Counter.current(c)
...>
...> Counter.increment c
...> 3 = Counter.current(c)
...>
...> {:this, :is, :a, :failure}
...> end
{:this, :is, :a, :failure}
iex> Counter.current counter
2
Link to this section Summary
Types
The label of a tuple returned from operation/0 that indicates it was
successful
A function around which transactional behavior will be wrapped
Option values used in defining a transaction function
Options used in defining a transaction function
Functions
Invokes the specified operation, changing the state of the specified server
only if the operation is successful. Success is indicated when the
operation returns {commit_instruction, term} (where commit_instruction is
as specified), in which case only the term is returned
Link to this section Types
The label of a tuple returned from operation/0 that indicates it was
successful.
operation() :: (GenServer.server() -> {commit_instruction(), any()} | any())
A function around which transactional behavior will be wrapped.
option() ::
{:function_name, :atom | binary()}
| {:server_name, :atom | binary()}
| {:commit_instruction, commit_instruction()}
| {:append_to_doc, binary()}
| {:since, Version.version()}
Option values used in defining a transaction function.
Options used in defining a transaction function.
Link to this section Functions
transaction(GenServer.server(), commit_instruction(), operation(), timeout()) :: any()
Invokes the specified operation, changing the state of the specified server
only if the operation is successful. Success is indicated when the
operation returns {commit_instruction, term} (where commit_instruction is
as specified), in which case only the term is returned.
Note: Within the operation, you must not send messages to the server.
Send messages instead to the GenServer.server/0 which is an argument to the
operation.