Workflow designThe long haul
I talked about some of the requirements for proper workflow design in my previous post. As a reminder, the top ones are:
- Cater for developers, not the business analysts. (More on this later).
- Source control isn’t optional, meaning:
- Multiple branches
- Can diff & review changes
- Merging
- Multiple people can work at the same time
- Encapsulate complexity
This may seem like a pretty poor list, because if you are a developer, you might be taking all of these as granted. Because of that, I wanted to display a small taste from what used to be Microsoft’s primary workflow engine.
A small hint… this kind of system is not going to be useful for anything relating to source control, change management, collaborative work, understanding what is going on, etc.
A better solution for this would be to use a tool that can work with source control, that developers are familiar with and can handle the required complexity.
That tool is called… code.
It checks all the boxes required, naturally. But it does have a distinct disadvantage. One of the primary reasons you want to use a workflow engine of some kind is to decouple the implementation of your business from the policies of the business. Coming back to the mortgage example, how you calculate late fees payment is fixed (in the contract itself, but usually also by law and many regulations), but figuring out whatever late fees should be waived, on the other hand, is subject to the whims of the business.
That is a pretty simple example, but in most businesses, these kind of workflows adds up. You can easily end up with dozens to hundreds of different workflows without the business being too big or complex.
There is another issue, though. Code is pretty good when you need to handle straightforward tasks. A set of if statements (which is pretty much all most workflows are) are trivial to handle. But workflow has another property, they tend to be long. Not long on computer scale (seconds), but long on people scale (months and years).
The typical process of getting a loan may involve an initial submission, review by a doctor, asking for follow up documentation (rinse – repeat a few times), getting doctor appraisal and only then being able to generate a quote for the customer. Then we have a period of time in which the customer can accept, a qualifying period, etc. That can last for a good long while.
Trying to code long running processes like that require us a very unnatural approach to coding. Especially since you are likely to need to handle software updates while the workflows are running.
In short, we are in a strange position: we want to use code, because it is clear, support software development practices that are essentials and can scale up in complexity as needed. On the other hand, we don’t want to use our usual codebase for that, because we’ll have very different deployment strategies, the manner of working is very different and there is a lot more involvement of the business in what is going on there.
The way to handle that is to create a proper boundary between parts of the system. We’ll have the workflow behavior, defined in scripts, that describe the policy of the system. These tend to be fairly high level concepts and are designed explicitly for the rule of business policy behaviors. The infrastructure for that, on the other hand, is just a standard application using normal software practices, that is driven by the workflow scripts.
And by a script, I meant literally a script. As in, JavaScript.
I want to give you a sneak peak into how I envision this kind of system, but I’ll defer full discussion of what is involved to my next post.
The idea is that we use the script to define our policy, and then we use that to make decisions and invoke the next stage in the process. You might notice that we have the state variable, which is persisted between invocations. That allow us to use a programming model that is fairly common and obvious to developers. We can usually also show this, as is, to a business analyst and get them to understand what is going on easily enough. All the actual actions are abstracted. For example, life insurance setup is a completely different workflow that we invoke.
In my next post, I’m going to drill down a bit into the details of this approach and what kind of features do we need there.
More posts in "Workflow design" series:
- (06 Mar 2019) Making the business people happy
- (05 Mar 2019) The thinking behind
- (28 Feb 2019) The long haul
- (27 Feb 2019) What you shouldn’t be looking for
Comments
Hey, that looks a lot like an Event Store index in Raven :) It'd be neat if there was an index type specifically for dealing with event stream projections, that started with an initial state and applied an aggregator function (like this) over subsequent event types.
Also, you wrote "process of getting a loan" but I think you meant "insurance" and not "loan" - Loan was the example in your other Raven ES article.
Ryan, Such an index is actually really easy to build for us, except that we also have to deal with deletions, which make things a lot more complicated.
And you are correct about loan / insurance. I actually started this with insurance questions, because the discussion that I had about this topic was in getting a loan and then having to go through the workflow of the getting insurance.
javascript is ugly. If only there was something like Boo :)
Oren, if you get the chance I think it would really benefit the community to have a larger realistic example of an Event centric multi-map reduce to create a projection. The 'count of comments on a post' is helpful when first starting out, but when your model starts to have multiple nested collections (eg patients->medications->doses) the LINQ syntax for defining the maps & reduce gets... unintuitive. Deletes suck, but at least soft deletes can make that less painful.
Javascript indexes look like they'd make it slightly cleaner, but then we lose compile time safety. Ugh.
Just wondering....did you look at xstate? It’s more of a state machine library, but there is common ground - you know.
Scala
Rafal, I wished it was still around and well, but I think we should just concede and admit that JS is here.
Ryan, If you can give me some concrete examples, I would be happy to analyze it in a blog post.
Frank, No, I didn't. This series of post aren't meant to show a solution, more a way of thinking
Comment preview