State Machines in Elixir with gen_statem

by Jake Prem

What is it?

gen_statem

  • Added in Erlang/OTP 19.0
  • Replaces the deprecated gen_fsm

GenServer vs gen_statem

  • GenServer for simple cases
  • gen_statem for more complex cases
    • Built in timeout functionality

Callback Modes

  • State Functions
    • State must be an atom
  • Handle Event Function
    • State can be any valid Erlang term
  • State Enter
    • A special case that will trigger an enter
      event on state changes
def callback_mode do
  :handle_event_function
  # or
  [:handle_event_function, :state_enter]
end

Return values

{:next_state, NextState, NewData, Actions[]}
{:next_state, NextState, NewData}

{:keep_state, NewData, Actions[]}
{:keep_state, NewData}

{:keep_state_and_data, Actions[]}
 :keep_state_and_data

{:repeat_state, NewData, Actions[]}
{:repeat_state, NewData}

{:repeat_state_and_data, Actions[]}
...

{:stop, Reason, NewData}
{:stop, Reason}
{:stop_and_reply, Reason, NewData, ReplyActions[]}
{:stop_and_reply, Reason, ReplyActions[]}

Return Actions

{:postpone, Boolean}

{:hibernate, Boolean}

# Cancelled on state_change, or {:state_timeout, :infinity}
{:state_timeout, Time}


{{:timeout, Name}, Time}

{:timeout, Time}

# --------------------------------
{:reply, From, Reply}

{:next_event, EventType, EventContent}

How do we use it?

Resources

Made with Slides.com