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 to transaction
  • :server_name — the name of the first parameter in the defined function; defaults to server
  • :commit_instruction — the commit_instruction/0 expected from an operation/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

Link to this type commit_instruction() View Source
commit_instruction() :: atom()

The label of a tuple returned from operation/0 that indicates it was successful.

Link to this type operation() View Source
operation() :: (GenServer.server() -> {commit_instruction(), any()} | any())

A function around which transactional behavior will be wrapped.

Link to this type option() View Source
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.

Link to this type options() View Source
options() :: [option()]

Options used in defining a transaction function.

Link to this section Functions

Link to this function transaction(server, commit_instruction, operation, timeout \\ 5000) View Source

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.