structured_io v0.9.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:
: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
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.
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.