Search documentation of Finitomata

# View Source Finitomata.Pool (Finitomata v0.21.2)

The instance of FSM backed up by `Finitomata`.

## FSM representation

    graph TD
        idle --> |init| ready
        idle --> |do| ready
        ready --> |do| ready
        ready --> |stop| done

Fully asynchronous pool to manage many similar processes, like connections.

The pool is to be started using `start_pool/1` directly or with `pool_spec/1` in the supervision tree.

`initialize/2` is explicitly separated because usually this is to be done after some external service initialization. In a case of `AMQP` connection management, one would probably start the connection process and then a pool to manage channels.

Once `initialize/2` has been called, the `run/3` function might be invoked to asynchronously execute the function passed as `actor` to `start_pool/1`.

If the callbacks `on_result/2` and/or `on_error/2` are defined, they will be invoked respectively. Finally, the message to the calling process will be sent, unless the third argument in a call to `run/3` is `nil`.

# Summary

## Types

actor()

The actor function in the pool

handler()

The handler function in the pool

id()

The ID of the Pool

naive_actor()

The simple actor function in the pool

naive_handler()

The simple handler of result/error in the pool

responsive_actor()

The actor function in the pool, receiving the state as a second argument

responsive_handler()

The actor function in the pool, receiving the state as a second argument

state()

Kind of event which might be send to initiate the transition.

t()

## Functions

__config__(key)

Getter for the internal compiled-in FSM information.

__generator__()

See `Finitomata.Pool.__generator__/1`

__generator__(this)

Returns the generator to be used in `StreamData`-powered property testing, based on the specification given to `use Estructura.Nested`, which contained

cast(content, options \\ [])

Casts the map representation as given to `Estructura.Nested.shape/1` to the nested `Estructura` instance.

cast!(content, options \\ [])
child_spec(init_arg)

Returns a specification to start this module under a supervisor.

config(key)

The convenient macro to allow using states in guards, returns a compile-time list of states for `Finitomata.Pool`.

get(data, key, default \\ nil)

Gets the value for the given key from the structure

initialize(id, payload_fun)

Initializes the started _FSM_s with the same payload, or with what `payload_fun/1` would return as many times as the number of workers.

parse(input)

Safely parses the json, applying all the specified validations and coercions

parse!(input)

Same as `parse/1` but either returns the result of successful parsing or raises

pool_spec(opts \\ [])

Child spec for `Finitomata.Pool` to embed the process into a supervision tree

put(data, key, value)

Puts the value for the given key into the structure, passing coercion and validation, returns `{:ok, updated_struct}` or `{:error, reason}` if there is no such key

put!(data, key, value)

Puts the value for the given key into the structure, passing coercion and validation, returns the value or raises if there is no such key

recalculate_calculated(data)
run(id, payload, pid \\ self())

The runner for the `actor` function with the specified payload.

start_link(payload)

Starts an FSM alone with `name` and `payload` given.

start_pool(opts \\ [])

Starts a pool of asynchronous workers wrapped by an FSM.

start_pool(id, count, state)

# Types

Link to this type

# actor()

View Source (since 0.18.0)

    @type actor() :: naive_actor() | responsive_actor()

The actor function in the pool

Link to this type

# handler()

View Source (since 0.18.0)

    @type handler() :: naive_handler() | responsive_handler()

The handler function in the pool

Link to this type

# id()

View Source (since 0.18.0)

    @type id() :: Finitomata.id()

The ID of the Pool

Link to this type

# naive_actor()

View Source (since 0.18.0)

    @type naive_actor() :: (term() -> {:ok, term()} | {:error, any()})

The simple actor function in the pool

Link to this type

# naive_handler()

View Source (since 0.18.0)

    @type naive_handler() :: (term() -> any())

The simple handler of result/error in the pool

Link to this type

# responsive_actor()

View Source (since 0.18.0)

    @type responsive_actor() :: (term(), Finitomata.State.payload() ->
                             {:ok, term()} | {:error, any()})

The actor function in the pool, receiving the state as a second argument

Link to this type

# responsive_handler()

View Source (since 0.18.0)

    @type responsive_handler() :: (term(), id() -> any())

The actor function in the pool, receiving the state as a second argument

Link to this type

# state()

View Source (since 0.18.0)

    @type state() :: :done | :ready | :idle | :*

Kind of event which might be send to initiate the transition.

## FSM representation

    graph TD
        idle --> |init| ready
        idle --> |do| ready
        ready --> |do| ready
        ready --> |stop| done

Link to this type

# t()

View Source (since 0.18.0)

    @type t() :: %Finitomata.Pool{
      id: any(),
      errors: list(),
      payload: any(),
      actor: any(),
      on_error: any(),
      on_result: any()
    }

# Functions

Link to this function

# __config__(key)

View Source (since 0.18.0)

    @spec __config__(atom()) :: any()

Getter for the internal compiled-in FSM information.

Link to this function

# __generator__()

View Source (since 0.18.0)

    @spec __generator__() ::
      StreamData.t(%Finitomata.Pool{
        actor: term(),
        errors: term(),
        id: term(),
        on_error: term(),
        on_result: term(),
        payload: term()
      })

See `Finitomata.Pool.__generator__/1`

Link to this function

# __generator__(this)

View Source (since 0.18.0)

    @spec __generator__(%Finitomata.Pool{
      actor: term(),
      errors: term(),
      id: term(),
      on_error: term(),
      on_result: term(),
      payload: term()
    }) ::
      StreamData.t(%Finitomata.Pool{
        actor: term(),
        errors: term(),
        id: term(),
        on_error: term(),
        on_result: term(),
        payload: term()
      })

Returns the generator to be used in `StreamData`-powered property testing, based on the specification given to `use Estructura.Nested`, which contained

## shape

    %{
      id: {StreamData, :atom, [:alias]},
      errors: [:term],
      payload: :term,
      actor: {StreamData, :constant, [&Function.identity/1]},
      on_error: {Finitomata.Pool.Actor, :handler, [:error]},
      on_result: {Finitomata.Pool.Actor, :handler, [[]]}
    }

The argument given would be used as a template to generate new values.

Link to this function

# cast(content, options \\ [])

View Source (since 0.18.0)

Casts the map representation as given to `Estructura.Nested.shape/1` to the nested `Estructura` instance.

If `split: true` is passed as an option, it will attempt to put `foo_bar` into nested `%{foo: %{bar: _}}`

Link to this function

# cast!(content, options \\ [])

View Source (since 0.18.0)
Link to this function

# child_spec(init_arg)

View Source (since 0.18.0)

Returns a specification to start this module under a supervisor.

See `Supervisor`.

Link to this macro

# config(key)

View Source (since 0.18.0) (macro)

The convenient macro to allow using states in guards, returns a compile-time list of states for `Finitomata.Pool`.

Link to this function

# get(data, key, default \\ nil)

View Source (since 0.18.0)

    @spec get(
      %Finitomata.Pool{
        actor: term(),
        errors: term(),
        id: term(),
        on_error: term(),
        on_result: term(),
        payload: term()
      },
      Estructura.Config.key(),
      any()
    ) :: any()

Gets the value for the given key from the structure

Link to this function

# initialize(id, payload_fun)

View Source (since 0.18.0)

    @spec initialize(Finitomata.id(), (pos_integer() -> any()) | any()) :: :ok

Initializes the started _FSM_s with the same payload, or with what `payload_fun/1` would return as many times as the number of workers.

Link to this function

# parse(input)

View Source (since 0.18.0)

    @spec parse(binary()) :: {:ok, struct()} | {:error, Exception.t()}

Safely parses the json, applying all the specified validations and coercions

Link to this function

# parse!(input)

View Source (since 0.18.0)

    @spec parse!(binary()) :: struct() | no_return()

Same as `parse/1` but either returns the result of successful parsing or raises

Link to this function

# pool_spec(opts \\ [])

View Source (since 0.18.0)

    @spec pool_spec(keyword()) :: Supervisor.child_spec()

Child spec for `Finitomata.Pool` to embed the process into a supervision tree

Link to this function

# put(data, key, value)

View Source (since 0.18.0)

    @spec put(
      %Finitomata.Pool{
        actor: term(),
        errors: term(),
        id: term(),
        on_error: term(),
        on_result: term(),
        payload: term()
      },
      Estructura.Config.key(),
      any()
    ) ::
      {:ok,
       %Finitomata.Pool{
         actor: term(),
         errors: term(),
         id: term(),
         on_error: term(),
         on_result: term(),
         payload: term()
       }}
      | {:error, any()}

Puts the value for the given key into the structure, passing coercion and validation, returns `{:ok, updated_struct}` or `{:error, reason}` if there is no such key

Link to this function

# put!(data, key, value)

View Source (since 0.18.0)

    @spec put!(
      %Finitomata.Pool{
        actor: term(),
        errors: term(),
        id: term(),
        on_error: term(),
        on_result: term(),
        payload: term()
      },
      Estructura.Config.key(),
      any()
    ) ::
      %Finitomata.Pool{
        actor: term(),
        errors: term(),
        id: term(),
        on_error: term(),
        on_result: term(),
        payload: term()
      }
      | no_return()

Puts the value for the given key into the structure, passing coercion and validation, returns the value or raises if there is no such key

Link to this function

# recalculate_calculated(data)

View Source (since 0.18.0)
Link to this function

# run(id, payload, pid \\ self())

View Source (since 0.18.0)

    @spec run(Finitomata.id(), Finitomata.event_payload(), pid()) :: :ok

The runner for the `actor` function with the specified payload.

Basically, upon calling `run/3`, the following chain of calls would have happened:

1. `actor.(payload, state)` (or `actor.(payload)` if the function of arity one had been given)
2. `on_result(result, id)` / `on_error(result, id)` if callbacks are specified
3. the message of the shape `{:transition, :success/:failure, self(), {payload, result, on_result/on_error}})` will be sent to `pid` unless `nil` given as a third argument

Link to this function

# start_link(payload)

View Source (since 0.18.0)

Starts an FSM alone with `name` and `payload` given.

Usually one does not want to call this directly, the most common way would be to start a `Finitomata` supervision tree or even better embed it into the existing supervision tree and start FSM with `Finitomata.start_fsm/4` passing `Finitomata.Pool` as the first parameter.

For distributed applications, use `Infinitomata.start_fsm/4` instead.

Link to this function

# start_pool(opts \\ [])

View Source (since 0.18.0)

    @spec start_pool(
      id: Finitomata.id(),
      payload: :term,
      count: pos_integer(),
      actor: actor(),
      on_error: handler(),
      on_result: handler()
    ) :: GenServer.on_start()

Starts a pool of asynchronous workers wrapped by an FSM.

Link to this function

# start_pool(id, count, state)

View Source (since 0.18.0)

    @spec start_pool(
      id :: Finitomata.id(),
      count :: pos_integer(),
      [actor: actor(), on_error: handler(), on_result: handler(), payload: :term]
      | %{
          :actor => actor(),
          optional(:on_error) => handler(),
          optional(:on_result) => handler(),
          optional(:payload) => :term
        }
      | [implementation: module(), payload: :term]
      | %{:implementation => module(), optional(:payload) => :term}
    ) :: GenServer.on_start()