UP | HOME
dix

Software Curmudgeon

Mumblings and Grumblings About Software

gen_fsm in Elixir
Published on Jan 24, 2016 by dix.

gen_fsm is a powerful behavior exposed in OTP. It is no longer exposed as part of the Elixir standard library, 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)
  end

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

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

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

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