Share
Embed
Spreading my love for Elixir and State Machines
João Moura
May 02, 2018
Transcript
46 slides
-
empty lock items add item in stock? no yes filled
checkout leave payed? no payed yes abandoned unblock items -
Functions must not Functions must not update values outside of
it update values outside of it -
Functions must not Functions must not depend on variables other
depend on variables other than its parameters than its parameters -
defmodule YourProject.UserStateMachine do use Machinery, states: ["created", "partial", "complete"], transitions:
%{ "created" => ["partial", "complete"], "partial" => "completed" } end -
defmodule YourProject.UserStateMachine do use Machinery, states: ["created", "partial", "complete"], transitions:
%{ "created" => ["partial", "complete"], "partial" => "completed" } end -
defmodule YourProject.UserStateMachine do use Machinery, states: ["created", "partial", "complete"], transitions:
%{ "created" => ["partial", "complete"], "partial" => "completed" } end -
defmodule YourProject.UserStateMachine do use Machinery, states: ["created", "partial", "complete"], transitions:
%{ "created" => ["partial", "complete"], "partial" => "completed" } end -
defmodule YourProject.UserStateMachine do use Machinery, states: ["created", "partial", "complete"], transitions:
%{ "created" => ["partial", "complete"], "partial" => "completed" } end -
Guard Functions Guard Functions def guard_transition(struct, "complete") do Map.get(struct, :missing_fields)
== false end def guard_transition(struct, "partial") do # ... end -
Before and after callbacks Before and after callbacks def before_transition(struct,
"complete"), do: struct def after_transition(struct, "complete"), do: struct -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
defmodule YourApp.Endpoint do # ... plug Machinery.Plug # ... end
config :machinery, interface: true, repo: YourApp.Repo, model: YourApp.User, module: YourApp.UserStateMachine