A Redis module that maintains a state machine on the server side.
** Notice, this is experimental, and under active development. **
The easiest way to investigate this capability, is to pull the latest docker. The following runs a redis instance on the default port, complete with a state machine.
docker run -p 6379:6379 -it redislabs/redisstatemachine:edge
A state machine is a JSON document containing key value pairs for machine state transitions. Let's look at the state machine template, via the SM.TEMPLATE
command.
redis-cli
SM.TEMPLATE
A state machine contains a map of states, a current state, and an initial state.
"{\"current\":\"\",\"map\":{},\"initial\":\"\"}"
Create a simple machine
redis-cli
SM.SET mymachine "{\"current\":\"\",\"map\":{},\"initial\":\"foo\"}"
Examine the machine via SM.GET
.
redis-cli
SM.GET mymachine
As we didn't specify a current state, the initial state is assumed:
"{\"current\":\"foo\",\"map\":{},\"initial\":\"foo\"}"
Let's create and interact with a complete state machine, using python, and redis-py. First, let's load the state machine template:
import redis
import json
r = redis.Redis(decode_responses=True)
tmpl = json.loads(r.execute_command("SM.TEMPLATE"))
Let's create a simple machine named mystatemachine. The default state will be foo, and we'll support states named bar
, blee
, and boo
. In our state machine, bar
will be able to move to states blee
and boo
, but only boo
will be able to return to blee.
tmpl['initial'] = 'bar'
tmpl['map'] = {"bar": ["blee", "boo"], "boo": ["blee"]}
r.execute_command("SM.SET", "mystatemachine", json.dumps(tmpl))
If we try to change our statemachine to an invalid state, Redis returns a nil.
x = r.execute_command("SM.MUTATE", "mystatemachine", "notastate")
print(x)
>>> None
If we try to change states to a valid state, we receive an ok.
x = r.execute_command("SM.MUTATE", "mystatemachine", "blee")
print(x)
>>> OK
Example the state machine, using the redis-cli we can example the machine using SM.GET
.
r.execute_command("SM.GET", "mystatemachine")
Notice the structure - we now have a map of states and transitions.
'{"current":"blee","map":{"bar":["blee","boo"],"boo":["blee"]},"initial":"bar"}'
As this is currently evolving, the canonical command set is available in the commands.json file, with usage tests available in the tests directory.
Build and run
make run
Module testing is currently integration based - and done with pytest, and python.
Set up a virtual environment, with your test dependencies
python -m venv .venv
source .venv/bin/activate
pip install -r tests/requirements.txt
Run the tests
pytest