Spreading my love for Elixir and State Machines

Spreading my love for Elixir and State Machines

98195776df79590269541395c699f816?s=128

João Moura

May 02, 2018
Tweet

Transcript

  1. 2.
  2. 4.
  3. 5.
  4. 9.

    empty lock items add item in stock? no yes filled

    checkout leave payed? no payed yes abandoned unblock items
  5. 13.

    Functions must not Functions must not depend on variables other

    depend on variables other than its parameters than its parameters
  6. 17.
  7. 18.
  8. 19.
  9. 20.
  10. 21.
  11. 28.
  12. 29.

    Before and after callbacks Before and after callbacks def before_transition(struct,

    "complete"), do: struct def after_transition(struct, "complete"), do: struct
  13. 31.

    defmodule FakeProject.ShoppingCartMachine do # We start by declaring all states

    and # each permitted transition. use Machinery, states: ["empty", "filled", "payed", "abandoned"], transitions: %{ "empty" => "filled", "filled" => ["payed", "abandoned"] } def guard_function(cart, "filled") do Item.has_stock?(cart.item) end def guard_function(cart, "payed") do Payment.status(cart) == :confirmed end def before_transition(cart, "filled") do Item.lock_form_cart(cart) cart end def after_transition(cart, "abadonned") do Item.unlock_form_cart(cart) cart end end
  14. 32.

    defmodule FakeProject.ShoppingCartMachine do # We start by declaring all states

    and # each permitted transition. use Machinery, states: ["empty", "filled", "payed", "abandoned"], transitions: %{ "empty" => "filled", "filled" => ["payed", "abandoned"] } def guard_function(cart, "filled") do Item.has_stock?(cart.item) end def guard_function(cart, "payed") do Payment.status(cart) == :confirmed end def before_transition(cart, "filled") do Item.lock_form_cart(cart) cart end def after_transition(cart, "abadonned") do Item.unlock_form_cart(cart) cart end end
  15. 33.

    defmodule FakeProject.ShoppingCartMachine do # We start by declaring all states

    and # each permitted transition. use Machinery, states: ["empty", "filled", "payed", "abandoned"], transitions: %{ "empty" => "filled", "filled" => ["payed", "abandoned"] } def guard_function(cart, "filled") do Item.has_stock?(cart.item) end def guard_function(cart, "payed") do Payment.status(cart) == :confirmed end def before_transition(cart, "filled") do Item.lock_form_cart(cart) cart end def after_transition(cart, "abadonned") do Item.unlock_form_cart(cart) cart end end
  16. 34.

    defmodule FakeProject.ShoppingCartMachine do # We start by declaring all states

    and # each permitted transition. use Machinery, states: ["empty", "filled", "payed", "abandoned"], transitions: %{ "empty" => "filled", "filled" => ["payed", "abandoned"] } def guard_function(cart, "filled") do Item.has_stock?(cart.item) end def guard_function(cart, "payed") do Payment.status(cart) == :confirmed end def before_transition(cart, "filled") do Item.lock_form_cart(cart) cart end def after_transition(cart, "abadonned") do Item.unlock_form_cart(cart) cart end end
  17. 35.

    defmodule FakeProject.ShoppingCartMachine do # We start by declaring all states

    and # each permitted transition. use Machinery, states: ["empty", "filled", "payed", "abandoned"], transitions: %{ "empty" => "filled", "filled" => ["payed", "abandoned"] } def guard_function(cart, "filled") do Item.has_stock?(cart.item) end def guard_function(cart, "payed") do Payment.status(cart) == :confirmed end def before_transition(cart, "filled") do Item.lock_form_cart(cart) cart end def after_transition(cart, "abadonned") do Item.unlock_form_cart(cart) cart end end
  18. 36.

    defmodule FakeProject.ShoppingCartMachine do # We start by declaring all states

    and # each permitted transition. use Machinery, states: ["empty", "filled", "payed", "abandoned"], transitions: %{ "empty" => "filled", "filled" => ["payed", "abandoned"] } def guard_function(cart, "filled") do Item.has_stock?(cart.item) end def guard_function(cart, "payed") do Payment.status(cart) == :confirmed end def before_transition(cart, "filled") do Item.lock_form_cart(cart) cart end def after_transition(cart, "abadonned") do Item.unlock_form_cart(cart) cart end end
  19. 37.

    defmodule FakeProject.ShoppingCartMachine do # We start by declaring all states

    and # each permitted transition. use Machinery, states: ["empty", "filled", "payed", "abandoned"], transitions: %{ "empty" => "filled", "filled" => ["payed", "abandoned"] } def guard_function(cart, "filled") do Item.has_stock?(cart.item) end def guard_function(cart, "payed") do Payment.status(cart) == :confirmed end def before_transition(cart, "filled") do Item.lock_form_cart(cart) cart end def after_transition(cart, "abadonned") do Item.unlock_form_cart(cart) cart end end
  20. 38.

    defmodule FakeProject.ShoppingCartMachine do # We start by declaring all states

    and # each permitted transition. use Machinery, states: ["empty", "filled", "payed", "abandoned"], transitions: %{ "empty" => "filled", "filled" => ["payed", "abandoned"] } def guard_function(cart, "filled") do Item.has_stock?(cart.item) end def guard_function(cart, "payed") do Payment.status(cart) == :confirmed end def before_transition(cart, "filled") do Item.lock_form_cart(cart) cart end def after_transition(cart, "abadonned") do Item.unlock_form_cart(cart) cart end end
  21. 40.

    defmodule YourApp.Endpoint do # ... plug Machinery.Plug # ... end

    config :machinery, interface: true, repo: YourApp.Repo, model: YourApp.User, module: YourApp.UserStateMachine
  22. 41.
  23. 42.