Redis based Finite State Machine.
Finist is a finite state machine that is defined and persisted in Redis.
Meet us on IRC: #lesscode on freenode.net.
Install Redis. On most platforms it's as easy as grabbing
the sources, running make and then putting the
in the PATH.
Once you have it installed, you can execute
redis-server and it
will run on
localhost:6379 by default. Check the
file that comes with the sources if you want to change some settings.
Finist requires a Redic compatible client. To make things
redic is listed as a runtime dependency so the examples
in this document will work.
require "finist" # Initialize with a Redis client, the name of the machine and the # initial state. In this example, the machine is called "order" and # the initial status is "pending". The Redis client is connected to # the default host (127.0.0.1:6379). machine = Finist.new(Redic.new, "order", "pending") # Available transitions are defined with the `on` method # `machine.on(<event>, <initial_state>, <final_state>)` machine.on("approve", "pending", "approved") machine.on("cancel", "pending", "cancelled") machine.on("cancel", "approved", "cancelled") machine.on("reset", "cancelled", "pending")
Now that the possible transitions are defined, we can check the current state:
machine.state # => "pending"
And we can trigger an event:
machine.trigger("approve") # => ["approved", true]
trigger method returns an array of two values: the first
represents the current state, and the second represents whether
a transition occurred.
Here's what happens if an event doesn't cause a transition:
machine.trigger("reset") # => ["approved", false]
Here's a convenient way to use this flag:
state, changed = machine.trigger("reset") if changed printf("State changed to %s\n", state) end
If you need to remove all the transitions for a given event, you
Note that every change is persisted in Redis.
Each event is represented as a hash in Redis, and its field/value pairs are the possible transitions.
For the FSM described in the examples above, the keys are laid out as follows:
# Current state finist:order (string) # Transitions for event `approve` finist:order:approve (hash) pending -> approved # Transitions for event `cancel` finist:order:cancel (hash) pending -> cancelled approved -> cancelled # Transitions for event `reset` finist:order:reset (hash) cancelled -> pending
$ gem install finist