View Source Protean.Builder (Protean v0.1.0)

API for defining Protean machines.

This module is imported by default when use Protean is spawned.

defining-a-machine

Defining a machine

At the outermost level, machines are specified as a keyword list, usually associated with the @machine module attribute of the defining module.

@machine [
  states: [
    # ...
  ]
]

For the most part, a machine definition is similar to a compound or parallel state definition, except that it allows for an addition :assigns option to specify the default assigns for the machine context.

@machine [
  assigns: %{
    # ...
  },
  # ...
]

The top-level machine can be parallel by specifying type: :parallel:

@machine [
  type: :parallel,
  states: [
    # ...
  ]
]

See compound/2 and parallel/2 for corresponding options.

Link to this section Summary

Functions

Builds an atomic state.

Builds a compound state.

Builds a delayed transition.

Builds a final state.

Builds a pattern-matching event transition.

Builds a parallel state.

Specification for a spawned process linked to a parent state.

Specification for a spawned stream linked to a parent state.

Specification for a spawned task linked to a parent state.

Builds a transition.

Link to this section Types

@type action() :: Protean.Action.t() | term()
@type actions() :: action() | [action()]
@type assigns() :: Enumerable.t()

Additional state stored in the machine context.

The specified assigns will be converted to a map/0.

@type atomic_state_option() ::
  {:spawn, spawns()}
  | {:entry, actions()}
  | {:exit, actions()}
  | {:always, transitions()}
  | {:after, delayed_transitions()}
  | {:on, event_transitions()}
Link to this type

atomic_state_options()

View Source
@type atomic_state_options() :: [atomic_state_option()]
Link to this type

compound_machine_option()

View Source
@type compound_machine_option() :: {:assigns, assigns()} | compound_state_option()
Link to this type

compound_state_option()

View Source
@type compound_state_option() ::
  atomic_state_option()
  | {:initial, state_name()}
  | {:states, states()}
  | {:done, transitions()}
Link to this type

compound_state_options()

View Source
@type compound_state_options() :: [compound_state_option()]
@type delayed_transition() :: [delayed_transition_option()]
Link to this type

delayed_transition_option()

View Source
@type delayed_transition_option() ::
  transition_option() | {:delay, milliseconds :: non_neg_integer()}
@type delayed_transitions() :: [delayed_transition()]
@type event_transition() :: {matcher :: function() | term(), transition()}
@type event_transitions() :: [event_transition()]
@type final_state_option() :: {:entry, actions()} | {:exit, actions()}
@type final_state_options() :: [final_state_option()]
@type machine_options() :: [compound_machine_option()] | [parallel_machine_option()]
Link to this type

parallel_machine_option()

View Source
@type parallel_machine_option() ::
  {:type, :parallel} | {:assigns, assigns()} | parallel_machine_option()
Link to this type

parallel_state_option()

View Source
@type parallel_state_option() ::
  atomic_state_option() | {:states, states()} | {:done, transitions()}
Link to this type

parallel_state_options()

View Source
@type parallel_state_options() :: [parallel_state_option()]
@type spawn_option() ::
  {:id, String.t()}
  | {:done, transitions()}
  | {:error, transitions()}
  | {:autoforward, boolean()}
@type spawn_options() :: [spawn_option()]
@type spawns() :: keyword() | [keyword()]
@type state() :: {state_name(), keyword()}
@type state_name() :: atom() | String.t()
@type states() :: [state()]
@type transition() :: [transition_option()]
@type transition_option() ::
  {:target, state_name()} | {:actions, actions()} | {:guard, Protean.Guard.t()}
@type transition_options() :: [transition_option()]
@type transitions() :: [transition()]

Link to this section Functions

Link to this function

atomic(name, opts \\ [])

View Source
@spec atomic(state_name(), atomic_state_options()) :: state()

Builds an atomic state.

Atomic states are simple states that cannot define children, but represent some intermediary state of the machine.

states: [
  atomic(:loading,
    # ...
  )
]

options

Options

  • :spawn - list of processes to spawn, see proc/2, task/2, stream/2;
  • :entry - actions to execute when entering this state;
  • :exit - actions to execute when exiting this state;
  • :always - transitions to immediately take when their guard is true, see transition/1;
  • :after - transitions to take after a given delay, see delay/2;
  • :on - transitions to take in response to an event, see match/2.
@spec compound(state_name(), compound_state_options()) :: state()

Builds a compound state.

Compound states have children defined by a :states list, of which only one will be active at a given time. They additional define an :initial attribute specifying which child should become active if we transition directly to the compound state.

states: [
  compound(:parent,
    initial: :child_a,
    states: [
      atomic(:child_a)
    ]
  )
]

Compound states can define a :done transition that will be taken if one of its final children become active. In the example below, the :parent state will transition to its sibling if the final :child_b state is entered.

states: [
  compound(:parent,
    initial: :child_a,
    done: transition(target: :sibling),
    states: [
      atomic(:child_a,
        # ...
      ),
      final(:child_b)
    ]
  )
]

options

Options

  • :initial (required) - child state to enter when entering the compound state;
  • :states (required) - one or more child states;
  • :done - transition to take if a final child state is entered;
  • all options available to atomic/2.
@spec delay(milliseconds :: non_neg_integer() | term(), transition_options()) ::
  keyword()

Builds a delayed transition.

Delayed transitions run automatically after the given delay so long as the machine is still in the state that defined it and any given guard allows it.

Accepts the same options as transition/1.

@spec final(state_name(), final_state_options()) :: state()

Builds a final state.

Final states are a variation of atomic states that represent some form of completion. Final states cannot define transitions of their own, but entering a final state can trigger a transition in a compound or parallel parent. See compound/2 and parallel/2.

states: [
  final(:completed)
]

options

Options

  • :entry - actions to execute when entering this state;
  • :exit - actions to execute when exiting this state (as a result of a parent transition).
Link to this macro

match(pattern, opts)

View Source (macro)

Builds a pattern-matching event transition.

Accepts the same options as transition/1.

example

Example

on: [
  match({:event_with_payload, _payload}, action: :save_payload),
  match(%Events.OtherEvent{}, target: :other)
]
@spec parallel(state_name(), parallel_state_options()) :: state()

Builds a parallel state.

Parallel states have child states defined by a :states list, all of which will be considered active concurrently when the parallel state is active.

states: [
  parallel(:parent,
    states: [
      atomic(:child_a,
        entry: :child_a_action
      ),
      atomic(:child_b,
        entry: :child_b_action
      )
    ]
  )
]

In the example above, transitioning to :parent would enter both child states and cause both of their entry actions to execute.

Parallel states can define a :done transition that will be taken when all of its children are in a final state. Usually, this means the parallel state's children are compound states with active final children.

states: [
  parallel(:parent,
    done: transition(target: :sibling),
    states: [
      compound(:compound_a,
        states: [
          atomic(:a_child1),
          final(:a_child2)
        ]
      ),
      compound(:compound_b,
        states: [
          atomic(:b_child1),
          final(:b_child2)
        ]
      )
    ]
  )
]

In the example above, the parent parallel state will transition to its sibling once both compound states have active final children.

options

Options

  • :states (required) - one or more child states, all of which will be concurrently entered when the parallel state becomes active;
  • :done - transition to take when all children are in a final state.
  • all options available to atomic/2.
@spec proc(term(), spawn_options()) :: keyword()

Specification for a spawned process linked to a parent state.

Link to this function

stream(spec, opts \\ [])

View Source
@spec stream(term(), spawn_options()) :: keyword()

Specification for a spawned stream linked to a parent state.

@spec task(term(), spawn_options()) :: keyword()

Specification for a spawned task linked to a parent state.

@spec transition(transition_options()) :: keyword()

Builds a transition.

options

Options

  • :target - the target state of the transition;
  • :actions - one or more actions that should be executed when the transition occurs;
  • :guard - condition that must be true in order for the transition to occur.

guards

Guards

See Protean.Guard TODO