View Source Finitomata.Flow (Finitomata v0.29.0)

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 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

Types

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)

@spec event(
  {Finitomata.id(), Finitomata.fsm_name()} | Finitomata.fsm_name(),
  Finitomata.Transition.event(),
  term()
) :: {:ok, term()} | :fsm_gone | {:error, Finitomata.State.payload()}

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

event(name, event, target_state, payload)

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