Behaviour for a durable FSM definition.
defmodule Checkout do
use GenDurable.FSM, version: 1, queue: "checkout", state: Checkout.State
@impl true
def step("start", %{state: s}), do: {:next, "await_pay", %{s | n: s.n + 1}}
def step("await_pay", ctx) do
case Enum.find(ctx.signals, & &1.name == "payment_confirmed") do
nil -> {:await, "payment_confirmed", ctx.state}
sig -> {:next, "ship", apply_payment(ctx.state, sig)}
end
end
def step("ship", _ctx), do: {:done, %{"shipped" => true}}
@impl true
def handle(reason, ctx) do
if ctx.attempt < 5, do: {:replay, ctx.state, backoff(ctx.attempt)}, else: {:stop, reason}
end
enduse options
:name— FSM name stored in thefsmcolumn (default:inspect(module)).:version—fsm_version(default1). Old versions coexist as separate registered modules; seeGenDurable.Registry.:queue— default queue for instances (default"default").:state— theGenDurable.Stateembedded-schema module (defaultnil, i.e. plain-map state).:initial— initial step forGenDurable.insert/2(default"start").
handle/2 defaults to {:stop, reason} and is overridable.
Summary
Callbacks
@callback handle(reason :: term(), ctx :: GenDurable.Context.t()) :: GenDurable.Outcome.t() | term()
@callback step(step :: String.t(), ctx :: GenDurable.Context.t()) :: GenDurable.Outcome.t() | term()