Skip to content

Instantly share code, notes, and snippets.

@mlconnor
Created July 9, 2013 20:31
Show Gist options
  • Save mlconnor/5961009 to your computer and use it in GitHub Desktop.
Save mlconnor/5961009 to your computer and use it in GitHub Desktop.
Node JS finite state machine
var U = require('underscore');
var sites = [
{"name" : "a", "time":4 },
{"name" : "b", "time":5 },
{"name" : "c", "time":6 },
{"name" : "d", "time":7 },
{"name" : "e", "time":8 },
{"name" : "f", "time":9 }
];
var currentSite = null;
var flowDef = {
"start" : "ready",
"transitions" : [
{
"from" : "ready",
"to" : "processing",
"action" : function() {
currentSite = sites.pop();
console.log("processing site", currentSite);
setTimeout(function() { console.log('timeout done'); wf.processEvent('job_complete'); }, currentSite.time * 200);
},
"guard" : function() {
return sites.length > 0;
}
},
{
"from" : "ready",
"to" : "done",
"guard" : function() { sites.length == 0; },
"action" : function() { process.exit(0); }
},
{
"from" : "processing",
"to" : "ready",
"event" : "job_complete",
"action" : function() {
console.log("job complete");
}
}
]
}
function Workflow(flow) {
this.flow = flow;
this.current = flow.start;
this.enterStartState = function() {
}
this.processEvent = function(eventName) {
console.log('processEvent(' + eventName + ')');
while (true) {
var foundTransition = false;
var relevant = this.findRelevant(eventName);
if ( relevant.length > 0 ) {
this.current = relevant[0].to;
eventName = undefined;
/* if an action is called then it could publish an event */
if ( U.has(relevant[0], 'action') ) {
relevant[0].action();
}
} else {
return;
}
}
};
this.findRelevant = function(eventName) {
var filter = { "from" : this.current };
if ( eventName != undefined > 0 ) {
filter.event = eventName;
}
var relevant = U.where(this.flow.transitions, filter);
var unguarded = U.filter(relevant, function(item) { return (! U.has(item, 'guard')) || item.guard(); });
return unguarded;
}
}
var wf = new Workflow(flowDef);
wf.processEvent();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment