Skip to content

shysank/go-gen-fsm

master
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?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 

This is a go implementation of erlang's gen_fsm

Why?

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
        }else{
            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.

Example

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

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages