Hello XState

If you haven't used state machine specifications for anything since leaving school, consider this your invitation to fix that.

I'll show a relatively straightforward but 100% real project that was able to benefit from creating and applying a state machine specification - come along for the ride!

Connectivity

This use case is from a project I worked around 2013 or so.

The basic setup is having two devices that need to talk to each other. Ideally they'll talk through a direct connection on the local network, but failing that, we'd like to fall back to a service-routed messages. If we end up routing, we'll run with reduced functionality to account for the higher latency.

The devices can authenticate independently to the service, and use it for an initial information exchange to set up material for authenticated, encrypted communication.

One of the goals for the project was to aggressively minimize connection time. Thus, we had a number of things going on in parallel, for example attempting to connect to a previously used address while contacting the service for a new connection, or doing service-relayed messaging until the local connection was established. Juggling how to route incoming and outgoing messages, and deciding when to tell applications using this library that a connection was usable and to what degree, ended up being a complex thing.

SCXML

State machines are a great tool for these sort of problems where inputs arrive at different times and what happens isn't fixed but based on some state. For trivial cases like 'run code if the widget is enabled, else ignore', you probably don't need a lot of formalism. But if you have many inputs and many states, a good model can help you walk through your system step by step, and (very importantly!) check it for consistency.

A state-transition table is also a great way of representing things, but I found it a bit clunky to work with nested states, and I didn't really have a good graphic visualization, which is handy when tracing paths through the state machine (tables are great for spotting omissions, though).

Something like a UML state machine can be pretty detailed, but I didn't have any up-to-date software on hand that would let me author this how I wanted it and also make the underlying model easily accessible.

In the end, I resorted to specifying my model in State Chart XML (or SCXML), authoring the document by hand. Reading the spec, it comes across as having an interesting history of supporting voice menus of all things, but it's based on a solid theoretical foundation and gets the job done.

This left me with an inert doc, however.

JScript code generation

Armed with my specification of choice, I wrote some JScript to parse up the SCXML document to generate an in-memory data model that could then be used for analysis, as well as generating state-transition tables for reviews, or graphviz files for diagrams. This helped explain and review the design with other developers working on related projects, and helped me think more thoroughly about the thing I was building.

As an aside, JScript is the Microsoft implementation of JavaScript back in Internet Explorer (the MSDN link is quite useless as the table of contents seems to have vanished). It was attractive back in the day because it was very easy to integrate into a build system by running it with cscript, the command-line interpreter.

As an extra bonus, I was able to write some functions to generate code for example with transition tables: given a state and an event, it would fill a small array with actions to take and states to transition to (for example, if a 'shutdown' event fired, a bunch of 'onexit' transitions would need to take place). I chose not to support parallel states, so a single state was enough. The size of the array was also a constant, derived from analyzing the longest possible sequence of actions.

Also, as an aside, models to deal with complex subjects that can be used for documentation, code generation and artifact generation is something that I've done other times.

The new hotness

XState is a project that looks quite promising. It looks much more feature-rich and mature than the scripts I had back in the day, and I'll joyfully give it a go the next time I need to model something of the sort.

Amusingly, it does adhere to SCXML, whose longevity I would attribute to the solid foundations of state machines. Harel state tables added hierarchy, concurrency and communications to earlier models in 1987, but early work in the fifties and sixties laid down the work to come.

Unsurprisingly, it doesn't run on cscript, but instead relies on nodejs, and is written in TypeScript rather than JavaScript.

Happy states!

Tags:  codingdesignjavascript

Home