Current section

Files

Jump to
state_server example switch_with_states.exs
Raw

example/switch_with_states.exs

defmodule SwitchWithStates do
@doc """
implements a light switch as a state server. In data, it keeps a count of
how many times the state of the light switch has changed.
On transition, it sends to standard error a comment that it has been flipped.
Note that the implementations are different between the two states.
"""
use StateServer, off: [flip: :on],
on: [flip: :off]
@type data :: non_neg_integer
def start_link, do: StateServer.start_link(__MODULE__, :ok)
@impl true
def init(:ok), do: {:ok, 0}
def flip(srv), do: StateServer.call(srv, :flip)
def query(srv), do: StateServer.call(srv, :query)
@impl true
def handle_call(:flip, _from, _state, _count) do
{:reply, :ok, transition: :flip}
end
defer handle_call
# we must defer the handle_call statement because there are both shared and
# individual implementation of handle_call features.
defstate Off, for: :off do
@impl true
def handle_transition(:flip, count) do
IO.puts(:stderr, "switch #{inspect self()} flipped on, #{count} times turned on")
{:noreply, update: count + 1}
end
@impl true
def handle_call(:query, _from, _count) do
{:reply, "state is off"}
end
end
defstate On, for: :on do
@impl true
def handle_transition(:flip, count) do
IO.puts(:stderr, "switch #{inspect self()} flipped off, #{count} times turned on")
:noreply
end
@impl true
def handle_call(:query, _from, _count) do
{:reply, "state is on"}
end
end
end