Last active
July 1, 2020 22:29
-
-
Save amclain/67b43f73e3b15cc86f957b3c1019ba19 to your computer and use it in GitHub Desktop.
A simple Elixir experiment with the OTP state machine gen_statem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Turnstyle do | |
@moduledoc """ | |
This state machine emulates a turnstyle gate that has a rotating bar | |
and a coin slot. If the gate is locked a coin must be inserted to unlock | |
it, and then the bar will rotate to let you through when it is pushed. | |
The bar will then lock back in position. | |
""" | |
@behaviour :gen_statem | |
def start_link do | |
:gen_statem.start_link(__MODULE__, nil, []) | |
end | |
def insert_coin(pid) do | |
:gen_statem.cast(pid, :insert_coin) | |
end | |
def push(pid) do | |
:gen_statem.cast(pid, :push) | |
end | |
# Callbacks | |
def callback_mode, do: [:state_functions, :state_enter] | |
def init(_) do | |
{:ok, :locked, nil} | |
end | |
def locked(:enter, _old_state, _data) do | |
IO.puts "Locked" | |
:keep_state_and_data | |
end | |
def locked(:cast, :insert_coin, data) do | |
IO.puts "Coin accepted" | |
{:next_state, :unlocked, data} | |
end | |
def locked(:cast, :push, _data) do | |
IO.puts "The bar doesn't move" | |
:keep_state_and_data | |
end | |
def unlocked(:enter, _old_state, _data) do | |
IO.puts "Unlocked" | |
{:keep_state_and_data, [{:state_timeout, 10000, :locked}]} | |
end | |
def unlocked(:state_timeout, :locked, data) do | |
IO.puts "Timed out - Your coin is returned" | |
{:next_state, :locked, data} | |
end | |
def unlocked(:cast, :insert_coin, _data) do | |
IO.puts "Your coin is returned" | |
:keep_state_and_data | |
end | |
def unlocked(:cast, :push, data) do | |
IO.puts "The bar rotates" | |
{:next_state, :locked, data} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment