Elixir Finite state machine

This package is inspired by ecto_fsm package

This package allows to use finite state machine pattern in elixir.

I have rewritten this library to make code simple and easier to use Install

def deps do
  [
    {:as_fsm, "~> 2.0.0"}
  ]
end

## Usage

First you to define FSM module

  defmodule TaskFsm do
    use AsFsm, repo: MyApp.Repo
    # by default state is check from column `state` of struct
    # you can specify your own with
    # use AsFsm, repo: MyApp.Repo, column: :status

    # define your event
    defevent(:start, from: :idle, to: :running)
    defevent(:pause, from: :running, to: :paused)
    defevent(:stop, from: [:running, :paused], to: :idle)

    # you can define some hook
    # it is automatically invoked if defined

    def before_start(context) do
      # do something then return context
      context
    end

    def on_start(context) do
      # do something then return context
      context
    end
  end

All appropriate event function will be generated. In this example we have

  def start(context), do: ....
  def paus(context), do: ....
  def stop(context), do: ....

Then use it

Understand the context

  @type :: %Context{
    struct: struct(),
    state: any(),
    valid?: boolean(),
    error: String.t() | nil,
    multi: Ecto.Multi.t() | nil
  }

## Event hook For each event you can define 2 hook

These 2 hooks must return a context. If you want to stop this transition, set valid? to false and return the context.

Custom persist struct

You can define your own function to persist struct state. This function is run within Multi so that it must return {:ok, data} | {:error, reason}

  def persist(struct, new_state, _context) do
    # do your update logic
    # or write log here
  end

Options