Finitomata.Flow (Finitomata v0.34.0)

View Source

The basic “brick” to build forks in top-level Finitomata instances.

Definition Syntax

To construct the Flow, one should use the declarative map with events and states, as a string.

%{
  "start" => %{valid_states: [:new], handler: &Foo.Bar.recipient_flow_name/3, initial: "✓"},
  "submit_name" => %{valid_states: [:started, :phone_number_submitted], handler: &submit_name/3},
  "submit_phone_number" => %{valid_states: [:started, :name_submitted], handler: &sumbit_phone/3},
  "commit" => %{valid_states: [:submit_name, :submit_phone_number], handler: &commit/3, final: "✓"}
}

and pass it to the use Finitomata.Flow as shown below. The declaration might be loaded from a file, or passed directly as a string.

defmodule OnboardingFlow do
  @moduledoc false
  use Finitomata.Flow, flow: "priv/flows/onboarding.flow"
end

Using with FSM

The FSM wanting to use the flow, must use forks: [state: [event: FlowImplModule, …]] option in a call to use Finitomata

  use Finitomata, fsm: @fsm, , forks: [started: [to_onboarded: OnboardingFlow]]

The compilation checks for both validity and consistency would be performed for OnboardingFlow.

Once the main FSM enters the state marked as forks: (:started in this particular example,) the FSM with the name {:fork, :started, MainFsmName} will be launched and the main FSM would wait for it to be finished. Upon termination, the flow FSM would send :to_onboarded event to the main FSM, enforcing it to move to the next state.

One might specify several Flows for the same event and state. In that case, Finitomata.on_fork/2 event must be implemented to decide what Flow to start in runtime.

  use Finitomata, fsm: @fsm, , forks: [s1: [evt: Flow1, evt: Flow2]]

  []

  @impl Finitomata
  def on_fork(:s1, %{} = state) do
    if state.simple_flow?,
      do: {:ok, Flow1},
      else: {:ok, Flow2}
  end

Flow management

Flow’s API is dedicated to the event/4 function. To start a transition for the FLow, one should call somewhat along the following lines.

Finitomata.Flow.event({:fork, :s1, "MainFSM"}, :submit_name, :commit)

The above will transition the Flow to the final state, terminating the Flow and sending :to_onboarded event to the main FSM.

Summary

Types

The option to be passed to control the event behaviour

The options to be passed to control the event behaviour

The result of event processing

The expected map to configure Finitomata.Flow

The expected flow step to configure Finitomata.Flow

Functions

Performs the transition to the predefined state, awaits for a result

Performs the transition to the desired state, awaits for a result

Fast-forwards the flow into one of the reachable states.

Types

event_option()

@type event_option() :: {:skip_handlers?, boolean()}

The option to be passed to control the event behaviour

event_options()

@type event_options() :: [event_option()]

The options to be passed to control the event behaviour

event_resolution()

@type event_resolution() ::
  {:ok, term()} | :fsm_gone | {:error, Finitomata.State.payload()}

The result of event processing

flow_map()

@type flow_map() :: %{optional(binary()) => flow_step()}

The expected map to configure Finitomata.Flow

flow_step()

@type flow_step() :: %{
  initial: boolean() | binary(),
  final: boolean() | binary(),
  valid_states: [Finitomata.Transition.state()],
  target_states: [Finitomata.Transition.state()],
  handler: (... -> term())
}

The expected flow step to configure Finitomata.Flow

Functions

event(id_name, event, payload \\ nil)

Performs the transition to the predefined state, awaits for a result

event(id_name, event, target_state, payload, options \\ [])

Performs the transition to the desired state, awaits for a result

fast_forward(id_name, target, options \\ [])

@spec fast_forward(
  {Finitomata.id(), Finitomata.fsm_name()} | Finitomata.fsm_name(),
  target ::
    Finitomata.Transition.state()
    | [Finitomata.Transition.state()]
    | Finitomata.Transition.Path.t(),
  options :: event_options()
) ::
  {:ok, [event_resolution()]}
  | {:fsm_gone, [event_resolution()]}
  | {:error, term()}

Fast-forwards the flow into one of the reachable states.