From Blockchain to AWS to TVs – The New Stack

I’ve noticed that state machines are mentioned a bit more often than they are explained. Nevertheless, they represent a standard tool in the developer’s arsenal, albeit easier to understand conceptually than they are to actually implement in a neat and reusable way.

A state machine (sometimes finite state machine) is a model of states and transitions between those states.

Think about the seasons. If we wanted to convert a year into a state machine of seasons, we know that the name of the states would be “spring”, “summer”, “autumn/autumn” and “winter”, and the transition between them would normally be ” wait three months .”

If we were to put this into simple code, we would have to:

  • Enumerate the seasons;
  • Relate which season transitions to which season;
  • Allow the seasons to pass on a method call;
  • Decide on a season start.

Here is my overly simple C# code for this requirement:

The memorable thing here is the definition of the seasons using enumeration types, which turn what would otherwise be strings into first-class citizens of code:

Now this is easy because the seasons work in a cycle. So the transitions are the same: You just jump to the next season. In fact, senior developers may refuse to recognize this as a state machine at all, due to how limited it is. However, it achieves its mission. While the names of the methods and variables are written to reflect the domain (seasons) for ease of reading, note that if we invented a new season, only two lines would need to be changed. We will return to the implementation later.

We recognize that most things in the real world do not have definitive states that they enter and exit cleanly. On the other hand, things like can modeled in this way, should be.

The Blockchain Use Case

Is a blockchain a state machine? After all, this is where many people have first seen the term used lately. We know what a block represents: ownership of cryptocurrency and transfer between parties. It is a (rather inefficient) state machine with an infinite number of states, even if they are equal. It has a current state and it can only continue after a transaction is properly resolved. Ethereum seems to describe itself as a state machine, adding the user content as part of the state to make it a “smart chain.”

Speaking of user content in a state, there’s a small tweak we can make to the simple state machine code to make it a bit more useful overall. This change allows a simple observer to subscribe to an event:

So now when we run the code, we see the seasons from the statements of a totally unrealistic farmer:

AWS and step functions

The other notable modern use of state machines is within AWS. Called Step Functions, they can be used for orchestration in the serverless world. This means that other Lambda functions can be triggered by the arrival of spring. What is interesting is the way they are represented in JSON:

There is only one state here, which appears to be both the initial state and self-terminating.

A typical state machine: television

Let’s look at another decent but much more typical state machine: a very basic TV.

Now, this isn’t a TV you have or want, but you know how it works. A large button on the front switches the TV on (to standby) and off again. When in standby, you can switch between channels with the remote control. We will ignore all the other things a TV must also have.

If we stay in C#, we now need two enumeration types: one for the commands and one for the states.

We can already see that we need to focus on the transitions, not the states themselves.

Unlike the seasonal cycle, not all commands are valid from a given state. We can’t turn on the TV twice in a row from the big button on the front. If I’m already on CHANNEL1, switching to CHANNEL1 won’t do anything. So while configuring, we need to add eight “when in this state, let this command move to that state” lines:

You can add observers or “side effects”, as I did in the previous example. You can imagine that a timer could be started when a channel changes, so that if the viewer falls asleep in front of a Japanese monster rampage or a cowboy showdown, the TV will turn off; in short, the TV’s API may need to subscribe to some state transitions.

When running, you can see that the disallowed transitions are politely ignored:

Conclusion

After you’ve written a few state machines, you’ll be in a better position to use existing library versions – and you no doubt will. These need to be totally generalized, so it might look a bit strict if you haven’t rolled some of your own and nailed this important design pattern.

Feature image via Shutterstock.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *