php[architect] logo

Want to check out an issue? Sign up to receive a special offer.

What Are Finite State Machines

Posted by on January 29, 2024

As developers, we’re constantly managing where entities are in some state. Entities like blog posts, multi-step user registration, and even UI elements can exist in multiple states, and we’re responsible for making sure that they’re always in a valid state. If something unexpected happens in those flows, it can cause bugs, which can cause us to lose paying customers.

Thankfully, our industry has decades of research and thought into the best ways to manage these states by using Finite-state Machines.

In this article, we’ll discuss what finite-state machines are, why you should be using them in your web application, and how to document them using mermaid.js syntax.

 

What Are Finite-State Machines?

A Finite-state Machine (FSM) is an abstract model that can be in exactly one of a finite (see that word popping back up again) number of states at a time. FSMs move from one state to another based on some input in what’s known as a transition.

When we define an FSM we do so by defining:

  1. The list of states
  2. The FSM’s initial state
  3. The transitions

When my professor first told us about FSMs my only thought was how much work that seems like. I think most developers think the same thing and attempt to solve problems that could be solved easily with FSMs using more questionable methods that make things worse for them later. I know I have done this before, and I’ve fixed systems that have had 20 variables that were replaced by a single FSM.

Once you learn about FSMs and how they’re constructed, you’ll see them everywhere. Stoplight? That’s an FSM. Door lock? Yup! Vending machine? Absolutely!

Let’s look at a stoplight FSM. In the United States, we have traffic lights that cycle through red (stop), green (go), and yellow (about to turn red so slow down) in a loop. There are also alternatives to this like flashing red and flashing yellow but I’m going to ignore that complexity to save space.

If we model that behavior into an FSM we get:

  1. List of states: Off, Red, Yellow, Green
  2. Initial state: Off
  3. Transitions
    1. Off to Red on boot
    2. Red to Green after X seconds
    3. Green to Yellow after Y seconds
    4. Yellow to Red after Z seconds

In this case, the input to determine when the transitions occur is based on a timer but it could just as easily be a user clicking on a UI element or receiving a webhook from an external provider.

You might notice that we didn’t define transitions that would cause problems like Yellow to Green. That’s because we never want this to happen so we’re going to add code to prevent this transition from ever occurring.

The last two pieces of terminology we’re going to cover are entry actions and exit actions. These are actions that are performed when the FSM enters or exits a state (respectively). Examples would include sending a notification and creating jobs to process data.

How to Model Finite-State Machines Using Mermaid

One of the more challenging parts of using FSMs in our application code is how it can quickly get out of control if we don’t have good documentation for all the states and their transitions.

We could use a tool to draw diagrams of our FSMs but these always become an afterthought because we have to open up an “extra” program to edit them. That’s why I prefer to use a tool that can convert text documents stored with our source code into a diagram that we can easily use.

The solution comes in the form of the syntax created by the Mermaid.js project. Mermaid.js provides a command line tool that we can use to convert a text file containing Markdown-inspired text into all kinds of diagrams.

Check out their documentation for a full list of supported diagram types. A few that are important to us as developers are of course state diagrams, but there are also sequence diagrams, Gantt charts, and Flowcharts.

If you want to try mermaid.js before installing it or you want to let a non-developer try it they can do so using https://mermaid.live/. It’s a powerful online tool that allows you to type the diagram out and see the results as you’re typing.

An example

Let’s work through an example, and in this example, create an FSM for a blog post’s state through its publishing flow. A post will start in a “Draft” state. When the author is ready to have their editor review the article, it can be marked as “Ready for Review.” The editor can either send it back to “Draft” to get updates or schedule it for being published. Then, when the publish date occurs, the state automatically switches to “Published.”

  1. List of states: Draft, Ready for Review, Scheduled, Published
  2. Initial state: Draft
  3. Transitions
    1. “Draft” to “Ready for Review”
    2. “Ready for Review” to “Draft”
    3. “Ready for Review” to “Scheduled”
    4. “Scheduled” to “Published”

To start, we’re going to put the string “stateDiagram-v2” on a line of its own. This will state that the following lines are a state diagram, so mermaid.js will know what to do with the next set of lines.

Each state in a mermaid diagram is represented as a string with no spaces. To start, we’re going to list our “Draft” and “Ready for Review” States. Note that we don’t have spaces in ReadyForReview or each word will show up on the diagram as its own state.

stateDiagram-v2
    Draft
    ReadyForReview

To define the transition between the two states, we’re going to put both of them on the same line with a “–>” between them.

stateDiagram-v2
    Draft --> ReadyForReview

This will cause them to be drawn with an arrow indicating the direction they can travel.

We can quickly fill out the remainder of the states:

stateDiagram-v2
    Draft --> ReadyForReview
    ReadyForReview --> Draft
    ReadyForReview --> Scheduled
    Scheduled --> Published

Notice that we can safely create a loop between the “Draft” and “Ready For Review” states because we can move “backward.”

I’m not super happy with the way “ReadyForReview” is all smashed together so let’s fix that. The Mermaid.js syntax allows us to define the state and then a label for the state by typing “{state name}: label” like so.

stateDiagram-v2
    ReadyForReview: Ready for Review
    Draft --> ReadyForReview
    ReadyForReview --> Scheduled
    ReadyForReview --> Draft
    Scheduled --> Published

There, that’s a LOT better.

Now you know the basics to create state diagrams in mermaid.js so you can continue to communicate with your team effectively.

Other Places We Can Create State Diagrams

The cool thing about knowing mermaid.js syntax is that it can be used in all kinds of places. Github has support for it in its markdown, so you can add a mermaid state diagram to any PR or comment by starting a code block using three backticks and then the word mermaid.

It’s very strict in its formatting, so you might have to play around with it before it will work.

PHP Storm also has a plug-in that allows us to type mermaid syntax and see the output in real-time. We can even do it in a scratch file.

What You Need to Know

  1. FSM machines allow us to define how an entity can flow through a system
  2. Define states, initial state, and transitions
  3. Can use tools to generate FSM diagrams from text using mermaid.js syntax

Tags:
 

Leave a comment

Use the form below to leave a comment: