gen_fsm in Elixir

gen_fsm is a powerful behavior exposed in OTP. It is no longer exposed as part of the Elixir StdLib, but using gen_fsm directly from Elixir is possible and pretty easy to do. I haven’t been able to find any good example code for this and thought it might be helpful.

As an example, I’ll implement a simple switch which begins in an off state and enters an on state after receiving enough events. To do this, we need to implement an init function, and functions for the two states: off and on.

defmodule Switch do
  def start_link(n \\ 10, opts \\ []) do
    :gen_fsm.start_link(__MODULE__, [n], opts)

  def init([n]) do
    {:ok, :off, %{n: n, received: 0}}

  def off({:event}, state) do
    if state.received + 1 > state.n do
      {:next_state, :on, %{state | received: state.received + 1}}
      {:next_state, :off, %{state | received: state.received + 1}}

  def on(_, state) do
    IO.puts "Turned on"
    {:next_state, :on, state}

For further reading on using gen_fsm, this chapter in Learn You Some Erlang is a good starting point.