Last night I saw that Maurice had a few tweets that caught my attention about flowchart, but this is the one that I want to talk about:
I thought about replying on twitter, but it’s a bit of a longer topic. When we were building the flowchart for VS2010, we considered a number of possible capabilities, but ultimately the capabilities customers were looking for fell into two categories:
- Arbitrary rework patterns
- Coordination patterns
We can describe the model of execution in the current flowchart to be one that supports arbitrary rework. You could also refer to this as GOTO. One benefit (and downside) of breaking out of the tightly scoped, hierarchical execution model that we see with the Sequential style of workflows (and in most procedural languages) is the fact there exists more freedom in terms of defining the “next” step to be taken. The simplest way to think about this is the following flowchart:
Now, this isn’t particularly interesting, and most folks who look at this will simply ask “why not a loop?” which in this case is a valid question. As a process gets more sophisticated (or if humans tend to be involved), the number of possible loops required gets rather tricky to manage in a sequential flow (consider the following rework scenario which includes “next steps” across conditional boundaries, and from some branches but not others.
Now, mathematically, we can describe the machinery in both of these machines as a set of valid transitions, and it is likely possible that there exists a complete mapping from any flowchart into procedural.
The second pattern we consistently saw was the use of a free form style of execution in order to build complex coordination patterns. The example I consistently return to (pointing back to a blog post I made back in the WF3 days)
Here I want to be able to coordinate a few different things, namely that 3 executes when 1 completes, 5 when 2, 4 when 1 AND 2, 6 when 3 AND 4 AND 5 complete. Here we’ve created a dependency graph that can’t be handled with the procedural constructs that we have. How could this happen? Imagine we’re trying to model the ranking process for a series of horse races. Task 3 can happen when Race 1 completes, as Task 5 can happen when Race 2 completes. Task 4 represents some work that requires the data from both Races. When those 3 tasks (3, 4, and 5) complete, I can move forward and take some action (like bet on the next race).
This type of pattern can be very powerful, and is often described by petri-nets. There exists a multitude of join semantics from simple AND joins to conditional joins (ranging from a simple “count” to a condition based on data).
How’d we get to where we are today?
Today, the flowchart in the .NET framework only supports the former pattern, that of arbitrary rework. How’d we get there. While we found a lot of value in both patterns what we found when we tried to compose them, we often got into places that became very hard to have predictable execution semantics. The basic crux of the design issue gets to the “re-arming” of a join. If I decide to jump back to task 3 at some point, what does it mean for 3 to complete? Do I execute 6 again right away, do I wait for 4 and 5 to complete a second time? What happens if I jump to 3 a second time? Now, there certainly exist formal models for this, and things like Petri-net define a set of semantics for these things. What we found though was that any expression of the model that took these things into account required a pretty deep understanding of the process model, and we lost one of the key benefits we see from a flowchart, which is that it is a simple, approachable model. This is not to say that we don’t think that the Coordination pattern is useful, or that petri-nets don’t ultimately hold the unified approach, we just did not have the time to implement a coordination pattern in VS 2010, and creating an approachable petri-net backed flowchart modeling style was something we’d need more time to get correct.
Where does this leave us?
If you’re looking at this and saying, “but I want coordination (or a full blown petri-net)”, there are a couple of options:
- Roll up your sleeves and write that activity. In the blog post above, I outline how you could go about building the coordination pattern, and with the new activity model, this would be simpler. The harder part is still writing a designer, and there is now some good guidance on free form designers in the source of the state machine on codeplex.
- Provide feedback on connect, when you do this it opens a bug in our bug database that our team is looking at daily. Describe your scenario, what you’re trying to do, and what you’d like to see. This type of customer feedback is vital to helping us plan the right features for the next release.