Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Spreading my love for Elixir and State Machines

Spreading my love for Elixir and State Machines

João Moura

May 02, 2018
Tweet

More Decks by João Moura

Other Decks in Programming

Transcript

  1. empty lock items add item in stock? no yes filled

    checkout leave payed? no payed yes abandoned unblock items
  2. Functions must not Functions must not depend on variables other

    depend on variables other than its parameters than its parameters
  3. Before and after callbacks Before and after callbacks def before_transition(struct,

    "complete"), do: struct def after_transition(struct, "complete"), do: struct
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. defmodule YourApp.Endpoint do # ... plug Machinery.Plug # ... end

    config :machinery, interface: true, repo: YourApp.Repo, model: YourApp.User, module: YourApp.UserStateMachine