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/0
expected from anoperation/0
passed to the function; defaults to:commit
:append_to_doc
— content to be appended to the defined function’s default@doc
attribute, such as example code:since
— the version expression to be assigned to the defined function’s@since
attribute
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
.