Tag Archives: fsm

State Machine discord as system error detection

It takes three subsystem state machines to create an error adaptive system.

This morning in the shower I was thinking about my last post on SCXML. What do you use as states in a system? Easy question, but then I thought, sure its internal states of a process, but how does the external “real” come into the picture, via guards? That could get messy in a very complex real world system. So, what if the external system is also modeled as a state machine?

Now we have two state machines, internal system and external system. What is the advantage? Well, each can have a peak into the other or using historical information, compute how the other works. Then if this prediction is not matched, it is an error. That is, if the internal machine is at state x and it knows that the external machine should be at state y at this point, and it is not, it is a system error. What to do?

This is where a third error machine would come into use. The function of this machine is to bring the other two into resonance, reduce the entropy, heat.

Depending on whether the machines are Mealy or Moore based, one would detect errors at particular points, events, transitions, or states.

I remember reading years ago about fault tolerant hardware systems. The minimum components was three; similar.

Hmmm. I don’t know what everything above really means, if anything. 🙂

Tangential subject: State machines, life cycles, etc:

For future thinking …

  • How does a FSM approach differ from a REST architecture.
    Building a RESTful Hypermedia Agent, Part 1
  • On the finite-state machine, a minimal model of mousetraps, ribosomes and the human soul“, Brian Hayes, Scientific American, 1983. Accessed November 6, 2011, at http://bit-player.org/bph-publications/SciAm-1983-12-Hayes-FSA.pdf
  • “Exception Handling Mechanism in Communicating Threads for Java”, Gerald. H. HILDERINK, Communicating Process Architectures 2005;
    Jan Broenink, Herman Roebbers, Johan Sunter, Peter Welch, and David Wood (Eds.), IOS Press, 2005
  • “Self-Healing in Modern Operating Systems”, Michael W. Shapiro, Sun Microsystems, QUEUE December/January 2004-2005.

 


Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Using Commons SCXML with Groovy

The Watch example is rewritten using Groovy language. The actual state machine document or spec is created using Groovy‘s MarkupBuilder. So essentially, no XML required.

Commons SCXML is

“State Chart XML (SCXML) is currently a Working Draft published by the World Wide Web Consortium (W3C). SCXML provides a generic state-machine based execution environment based on Harel State Tables. SCXML is a candidate for the control language within multiple markup languages coming out of the W3C (see Working Draft for details). Commons SCXML is an implementation aimed at creating and maintaining a Java SCXML engine capable of executing a state machine defined using a SCXML document, while abstracting out the environment interfaces. ”

I think the emphasis on XML in this project is unfortunate since the state chart could be specified in alternative formats, albeit with loss of some of the high end features of XML. For example, with Groovy, a compiled scripting language on the JVM, the following is a non-XML specification. It creates an XML as output, but the same approach could be used to bypass the XML entirely.

	def writer = new StringWriter()
	def builder = new MarkupBuilder(writer)

	builder.scxml(
	  xmlns:namespace,version:"1.0",initialstate:"reset"){
	     state(id:"reset"){
		   transition(
			event:Trans.TSTART.name,target:"running"){
		   }
	     }
	     state(id:"running"){
		   transition(
			event:Trans.TSPLIT.name,target:"paused"){
	           }
	           transition(
		        event:Trans.TSTOP.name,target:"stopped"){
		   }
	     }
	     state(id:"paused"){
		    transition(
		        event:Trans.TUNSPLIT.name,target:"running"){
	    }
	    transition(
			event:Trans.TSTOP.name,target:"stopped"){
		    }
			}
	     state(id:"stopped"){
		   transition(
			event:Trans.TRESET.name,target:"reset"){
		   }
	     }
	}

	new File("sm.xml").setText(writer.toString())
	writer.close()

Listing one below is a version of the Watch example presented on the Commons SCXML site. Instead of subclassing the AbstractStateMachine, this version uses the SCXMLExecutor and extends SCXMLListener. The listener allows the engine to invoke methods on the demo class by setting itself as the invoker: executor.registerInvokerClass(“watch”,getClass());

Note: The Groovy Grab will not work in Eclipse. I just put the required jars in the build path. The grab will work in the command line.

Listing one

// file: ScxmlDemo.groovy
import groovy.xml.*
import groovy.grape.*

import java.awt.datatransfer.Transferable;
import java.lang.reflect.Method
import org.apache.commons.scxml.*
import org.apache.commons.scxml.io.*
import org.apache.commons.scxml.env.*
import org.apache.commons.scxml.invoke.*
import org.apache.commons.scxml.model.*
import org.apache.commons.scxml.env.jsp.*

@Grapes(
	[@Grab('commons-scxml:commons-scxml:0.9'),
	@Grab('commons-el:commons-el:1.0'),
	@Grab('commons-logging:commons-logging:1.1.1')]
)

/**
 *
 * Demo of
 * "...State Chart XML (SCXML), which is a general-purpose
 * event-based state machine language that combines
 * concepts from CCXML and Harel State Tables."
 *
 * Invocation:
 *   groovy srcScxmlDemo.groovy
 * @author jbetancourt
 *
 */
public class ScxmlDemo implements SCXMLListener {
	SCXMLExecutor executor
	def namespace = "http://www.w3.org/2005/07/scxml"
	Map methods = [:]

	enum Trans{
		TSTART("watch.start"),TSPLIT("watch.split"),
		TSTOP("watch.stop"),TUNSPLIT("watch.unsplit"),
		TRESET("watch.reset");

		String name;
		public Trans(String s){
			name = s
		}
	}

	/**   */
	public ScxmlDemo(){
		["doReset","doRunning","doPaused","doStopped"].
		each{
			methods.put(it,
				this.getClass().
				getDeclaredMethod(it, new Class[0]))
		}
	}

	/** Instead of writing XML, we use a DSL builder to create it */
	def createScxmlDoc(){
		def writer = new StringWriter()
		def builder = new MarkupBuilder(writer)

		builder.scxml(
		  xmlns:namespace,version:"1.0",initialstate:"reset"){
		     state(id:"reset"){
			   transition(
				event:Trans.TSTART.name,target:"running"){
			   }
		     }
		     state(id:"running"){
			   transition(
				event:Trans.TSPLIT.name,target:"paused"){
		           }
		           transition(
			        event:Trans.TSTOP.name,target:"stopped"){
			   }
		     }
		     state(id:"paused"){
			    transition(
			        event:Trans.TUNSPLIT.name,target:"running"){
			    }
			    transition(
				event:Trans.TSTOP.name,target:"stopped"){
			    }
				}
		     state(id:"stopped"){
			   transition(
				event:Trans.TRESET.name,target:"reset"){
			   }
		     }
		}

		new File("sm.xml").setText(writer.toString())
		writer.close()
	}

	/**   */
	public void execute(){
		createScxmlDoc()
		def eh = new
			org.apache.commons.scxml.env.SimpleErrorHandler()
		SCXML model = SCXMLParser.parse(
				new File("sm.xml").toURI().toURL(), eh)

		executor = new SCXMLExecutor()
		executor.setRootContext(new SimpleContext())
		executor.setEvaluator(new ELEvaluator())
		executor.setErrorReporter(new SimpleErrorReporter())
		executor.setStateMachine(model)
		executor.setEventdispatcher(new SimpleDispatcher())
		executor.addListener(model, this)
		executor.registerInvokerClass("watch",getClass());

		executor.go()

		fireEvent(Trans.TSTART.name);
		def status = executor.getCurrentStatus().
				getAllStates()
		status.each{ println "Now state is: ${it.id}" }
	}

	/**  */
	public void fireEvent(name){
		def evts = [
			new TriggerEvent(name,
			TriggerEvent.SIGNAL_EVENT, null)
		];

		executor.triggerEvents(evts as TriggerEvent[])
	}

	/**  */
	def invoke(id){
		try {
			def name = 'do' + id.substring(0,1).
				toUpperCase() + id.substring(1)
			def method = methods[name]
			method.invoke(this, new Object[0]);
			return true
		}catch(Exception ex){
			ex.printStackTrace()
		}

		return false
	}

	/**  */
	@Override
	public void onEntry(
	final TransitionTarget entered) {
		invoke(entered.getId());
	}

	/**
	 *
	 * @param from The "source" transition target.
	 * @param to The "destination" transition target.
	 * @param transition The transition being followed.
	 */
	@Override
	public void onTransition(
	   final TransitionTarget from,
	   final TransitionTarget to,
	   final Transition transition) {
		// nothing to do
	}

	/**
	 *
	 * @param exited The transition target being exited.
	 */
	@Override
	public void onExit(final TransitionTarget exited) {
		// nothing to do
	}

	// the activities
	def show(s){println "I'm '$s' ..."}
	public void doReset() {show('reset')}
	public void doRunning() {show('running')}
	public void doPaused() {show('paused')}
	public void doStopped() {show('stopped')}

	public static main(args){
		def main = new ScxmlDemo()
		main.execute()
	}
}

Example run:

groovy src/ScxmlDemo.groovy
I'm 'reset' ...
I'm 'running' ...
Now state is: running

Who needs state machines?
Many applications would probably benefit from having the control flow managed by some kind of flow engine. Sometimes we wind up with the internal object’s implicit FSM mixed into the application FSM in tangles of confusion and brittleness.

Modern software engineering is just the use of more ingenious complex frameworks for obfuscating the finite state machines really being created. This is especially true in the Java world, where there is a tendency toward frameitis.

Summary
Presented was an example of implementing the Watch example application using the Groovy programming library. The Groovy MarkupBuilder gives a “better” language then XML for creating the state machine document.

SCXML can be the basis of a State-Oriented Programming approach.

Updates

  • Mar 24, 2012: It is possible to forgo the creation of an XML descriptor and use a Groovy DSL approach to constructing the SCXML state machine. The following links discuss Groovy DSL usage.
    1. Groovy FSM DSL (toy version). Note does not implement SCXML
    2. Writing Domain-Specific Languages
  • Added link to another Groovy based SCXML util: commons-scxml

Links

JavaScript state machine libraries


Miles Davis – So What

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.