Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

This is a go implementation of erlang's gen_fsm


Erlang's gen_fsm provides a nice way of implementing finite state machines, which can be described as:
State(S) x Event(E) -> Actions(A), State(S')
There are a couple of things nice about this:

  • Event handlers for different states are just functions with states as function names, and event data as inputs.
  • Each instance of fsm is run as a separate process providing concurrency.

How to implement?

  • Implement the init function to set initial state
    func (f *MyFsm) Init(args... interface{}) State

  • Implement event handlers for all states. An event handler looks like this
    func (f *MyFsm) State_Event(event_data) (State, Timeout)
    where State is the next desired state, and timeout the amount of time in time.Duration to wait to send a timeout event if nothing happens.
    For eg. a door in Locked state will transition to Open, when the right code is entered. This will look like this:

func (d *Door) Locked_Button(code rune) (go_gen_fsm.State,time.Duration){
        if match(code){
            return "Open", 5 * time.Second
            return "Locked", -1

Here, the door will open after the correct is entered, and a timeout event will be sent after 5 seconds. To handle the timeout event, we should define a handler for that. This will look like this:

func (d *Door) Open_Timeout() (go_gen_fsm.State){
        return "Locked"

Now, the door will again be Locked after the timeout.

  • Create an instance of your fsm and start go_gen_fsm
    f := new(MyFsm)
    g := go_gen_fsm.Start(f, args...)

where args will be passed to the Init method to initialize the fsm.

  • Finally, To send an event, use the SendEvent api provided by GenFsm (from the above step)
    g.SendEvent(EventName, EventData...)

How it works?

Internally, go_gen_fsm starts a go routine when Start is invoked. This acts as an event loop listening to events, and uses reflection to invoke the appropriate handlers, thereby providing concurrency.


A full implementation of a door state machine described here is implemented in the sample package.


No description, website, or topics provided.






No releases published


No packages published