What the… State Machine

Sezen de Bruijn
ITNEXT
Published in
13 min readMar 22, 2021

--

Some terms are useful to be familiar with when you start working with Case Management. I’ve decided that this year I’m going to do the research and explain some of these concepts as easily as I possibly can. Then I will tie it to the Case Management framework as we implement it. And I will evaluate whether it is worth it along the way.

(You’re not required to read the whole thing of course, if you want to tap out after just learning the concept, that is fine by me. Alternatively, if you want to learn only about Case Management Frameworks version of state Machines jump to So how do you do this Case Management Framework?

Today… We are going to talk about state machines.

State Machine

A State Machine is a set of states and all possible transitions between them. This does not sound revolutionary, but it kind of is. If you are used to programming sequential processes you might think: “What is the use of that? State transitions naturally arise from the process.”

But here is the kicker, state machines are not just a way to remember which state transitions are possible, but also a way to separate states from the events that lead to them. This is very convenient as it breaks your projects down to much smaller chunks. Rather than having to understand an entire process you just need to know how the case gets to a specific state and what happens when it gets there.

The State Machine approach is as follows:

  1. You define the states
  2. You define the potential transition between these states
  3. You implement the evaluation of whether such a transition needs to take place
  4. Magic!

Let’s take a good Dutch example:

If you take your bike to the shop it will start off as ‘broken’, our initial state. You can only have one initial state. The broken bike might be fixed, or judged beyond repair, which are two follow-up states. After a bike is fixed you’ll go into a payment process, which will have potential stages such as ‘paid’, ‘payment term exceeded’ and ‘debt sold off’. So far, it’s quite simple and you could easily model it in BPT as something like this:

(Quick note, the way I put the timer here is for illustrative purposes, it is slightly different if you implement it for real, but I wanted to keep my illustration simple. This is the part of the article where I’ll keep things simple even at the cost of accuracy.)

Now say that this is a very young bike shop, they only have done a few repairs, and want to be able to extend and adjust this process as they grow. In that case it might be useful to take a modelling approach where things are modelled in a more loosely coupled way. Making a change in a sequential process would mean you need to look at the way your section interacts with all other parts of the process. You might not be able to foresee all consequences.

In a state machine things are not quite so interconnected, and therefore this is a method that enables you to build processes that are less rigid. You might not know what the path is that a bike will take from entering a shop to exiting the shop, but you know some of the statuses it might pass along the way. And as the shop expands and adds more services you will adjust the model.

So how is the bike repair modelled in a state machine?

In a state machine each transition between states is triggered by an event. If a once-broken bicycle has been fixed by a repairman, this event is what moves it to the ‘Repaired’ state. Reaching the repaired state is the event that triggers the payment term clock to start counting down, and the clock running out is the event that will move the bike to the Delinquent Debt state, unless the debt is paid.

To extend upon this we could add a ‘no capacity status’ which automatically gets set when a new broken bike comes into the shop and there is no availability. Then when a new repairman gets hired and the available capacity is more than 20% above norm, the most recently rejected repairs might automatically be moved to a ‘capacity is now available’ state and receive an email that they can come in after all.
Or if we add a financial department in the organization which will put debtors on a payment plan, we will add a state for Payment Plan, and add a transition from Delinquent debt to Payment Plan. And perhaps a transition back as well for when people start to default on the payment plan.

Once we have the basics set up, adding new states, new transitions and new logic is a relatively small and self-contained effort. We essentially set out to create natural processes that evolve as the organization and the people do, rather than laying down a strict set of processes upfront.

So setting up State Machines can make your Case Management a lot more flexible.

(Things are about to become technical now, so if that’s not for you, please skip to “Was it worth it?”)

So how do you do this with Case Management Framework?

In order to set this up we need to do the following:

  1. Set up an application with a Business Entity and a Business Process
  2. Set up a State Machine
  3. Use the State Machine to make our application

Lets go!

For the MVP we are going to avoid all automation for a second and do everything based on human interactions.

We start with setting up a Business Entity for the repair request, making an associated Business Process and configure the Case Definition and Case Status in accordance with this tutorial.

Feel free to forget about that Business Process for now, I’ll tell you when it becomes relevant! Then we add the allowed State Transitions into the model using this Tutorial.
I’ve included a screenshot of the bootstrap action that I’ve built using these tutorials. It fills the metadata database tables with the correct information for our state machine.

(Read “What the… Case Management framework” if you don’t understand what I mean with that. )

After publishing the configuration module to trigger the bootstrap action we will build an action through which we can Create the Repair Request. As you can see in the screenshot this action starts with initializing a case first so that we can use its id for our Repair Request. This way the data and the Business Process are going to be linked together.

Now it is time to build the UI.

We will build two simple screens by scaffolding based on the Repair Request entity. The save button in the detail screen we will replace with our new Create action for the Repair Request, so that we initiate the case when we create the request.
We also add a DataAction to get the possible statuses based on the RepairRequestID. For this we will use the Case Management Frameworks’ Case_GetAllPossibleStatus, which you can find in CaseServices_API.

To test whether our State Machine works correctly we will now add a list element in the screen connected to the DataAction. In the list element we will add a button element, with as label the StatusName.

The onclick action calls on the Case_UpdateStatus action that, using the RepairRequestId and CaseStatusId, updates the status of the case, and then refreshes the data action.

Now we will test by creating a request and then opening it up. We get the choice between ‘Stolen’, ‘Repaired’ and ‘Beyond Repair’.

Clicking on Repaired we now get new options, namely ‘Stolen’, ‘DelinquentDebt’ and ‘Paid’. This will work all the way until we’ve reached the terminal state ‘Case Closed’, as this State naturally doesn’t have any followup states.

We have successfully implemented a low level State Machine. Now let’s go and add some automation!

Lets automate

Remember that process we created at the beginning of this whole implementation and linked to the case, then promptly forgot all about? Time for that to become relevant again!

For this implementation I will use a beginner-level pattern that I’d like to call a star pattern. At the heart of the star will be the logic that checks which status transitions are possible. For the possible transitions it might require to start an automated or human activity to check whether the transition conditions are met. These activities form the point of the star, and when they are executed they will point back to the heart.

In our bikeshop the heart of the star will be a decision point called NextStatuses. The goal of this decision is to determine which action should happen next, based on the potential next statuses and other information.

Because our bikeshop example is very simple we will only focus on the allowed next statuses. So first we use the Case_CetAllPossibleStatus action to get a list of potential next statuses, just like we did on the screen. We will then cycle over that list and in a switch check whether the possible next status is Repaired or BeyondRepair. If so, we will connect to a decision outcome called RepairJob. RepairJob is the action that will check which of these states is tha appropriate next stage.

If the potential next stage is Payment or Delinquent Debt, we will connect to the PaymentTermStarts decision outcome. (See picture directly below.)

Remember how a State Machine was simply a set of states and ways to transition through those states?

The point of this part of the logic is simply to see which potential transitions take place and then create a new activity to evaluate which Status should be the next one. Allow me to wax lyrically about the beauty of such an approach:

If you think in a sequential fashion you will see a process mostly as a set of automated and or human activities linked together, occasionally leading to a status change. The status is just there to make clear to humans what the status of the process is.
When building a state machine it is essential to shift your perspective. In a state machine a process is a set of statuses and activities are only there to determine which state transition should take place.

In State-Machine activities are important only in the way they enable accurate state transitions. They are utterly unimportant in their own right.

Having said that, let’s now spend half this article on Activities… 🙃

In the next section we will look at three activities and how they aid the transition between states:

  1. Repair Job
  2. Payment Term Starts
  3. Case Closed

Repair Job

When we need to decide whether to transition to the Repaired Stage or the BeyondRepair stage the Repair Job activity will be started. It is a Human activity called “RepairTask” and closes when a RepairRequest with the RepairRequestId in question gets updated.

The actual human task of checking out the bike is what determines which of the two possible transitions takes place. If the bike is repaired then the case transitions from the status ‘Broken’ to the status ‘Repaired’. If the bike cannot be repaired the case will transition from the status ‘Broken’ to the status ‘Beyond Repair’. The application cannot actually read the repairman’s mind (yet!), so for our purposes the human task that determines this transition is actually the action of updating the Repair Request record.

This update closes the Human Activity and the closing of the activity triggers an action that runs when this activity is closed. The On Close action gets the Repair Request from the database, checks whether it is set to Beyondrepair and updates the status based on this information, like this:

After this action runs we go back to the Next Statuses decision to figure out what should happen next.

Payment Term Starts

When the next status transition is either to“Delinquent Debt” or “Paid” the WaitTillPaymentTermRunsOut activity starts up to determine which should take place. The WaitTillPaymenTermsRunOut activity is a timer that closes on an update on the Repair Request or times out after 5 days.

When it closes an action runs to figure out whether the time ran out or the payment was received. Just as in the previous action it gets the data from the Repair Request from the database, checks whether the bill was paid and updates the status accordingly.

After this action runs the process goes back to the NextStatuses step.

Case Closed

This is our final activity. Case Closed is the only one we don’t need to satisfy any conditions for. We reach this activity by failing to satisfy the criteria for any of the other outcomes.

The activity we execute when we get here is the final State transition. We simply update the status to case closed.

This leaves us with a fully automated, if light-weight State Machine, that looks like this:

Was it worth it?

Now that we have made our State Machine you might wonder if all this effort was worth it. Why take this long detour on an application that can be built perfectly fine with a simple BPT process.

If that’s what you are thinking: Good! That is the question you should always ask yourself before building yourself a State Machine or indeed any CMF application. If you can take an easier road than that might just be the right solution.

In this case we see some benefits from the State Machine approach: it has become much easier to add new functionality in the application. To do so we just add the states and transitions into the database, add it to the evaluation in the decision to see if we need to execute the related activity and build the related activity. We do not have to figure out where exactly this would fit into an already existing sequential process.
We also have an easier way to adjust process here, as we now have a situation where statuses beget statuses. Want to make it possible to ask for money for the time you invested in checking the bike even after you’ve judged the bike beyond repair?

Simply change the transition from ‘Beyond Repair’ to ‘Case Closed’ into a transition where you move from “Beyond Repair” to “Paid” or “Delinquent Debt”, and you will automatically move to the timer as a next step.

As a small test I implemented a waiting listing mechanism, where we put bikes on the waiting list if we were already at capacity. The whole implementation took half an hour, and was very simple to do, because the State Machine approach severely limited the impact. I just had to extend the state transition conditions in repair job a bit.

Finally, it is a way to move towards dynamic processes as well. In a State Machine you can model it such that Cases can switch to completely different Statuses that you would usually not connect in a sequential process. This allows you to build applications that work a bit more ad hoc just like humans do.

These are the benefits of the State Machine approach.

However setting up the case already took some time, and then we had to actually model the State transitions we wanted to use. It was a bigger time investment upfront than if I would have done the same things with a simple sequential process.

So whether it was worth it depends a little bit on whether our bike shop is going to be evolving their processes and will extend way beyond our current process. If all they wanted to do was this simple process, a business process would have more than sufficed.

But if they anticipate a lot of change or growth in their processes, the State Machine might help them out.

Some final thoughts.

State Machines are an interesting approach of modelling to me. By putting the states at the forefront and making the activities subservient to them, we put the focus on the goals of the process rather than on the way we get there.

It is a philosophically interesting shift in thinking that might allow us to win back some control over the way that IT works. Too often I see people serving an institutionalized process, rather than the process serving the people. State Machines could help tackle that by shifting the focus to goals rather than activities, and avoiding a rigidly charted path.

Even so, I think that one can still build obnoxious processes with a State Machine or build a natural process using the sequential design approach. The State Machine will not be the only tool in your toolkit, nor will it fix all of your problems, but it is an interesting tool nonetheless.

--

--

Low-Code Solution Architect ★ helping you build IT Fast, Right and for the Future ★ Let’s just have some fun :-)