Dave Green's WebLog

Workflow

  • Which Style of Workflow When?

    Windows Workflow Foundation supports three basic styles of workflow:  Sequential, State Machine and Data-Driven. 

    I get a lot of people asking me which style is right for their problem, so I thought I’d share my thoughts on this with you all.

    Let’s start with a simple problem.  I want Fred to review a document, then Joe to approve it, and finally I want to send it to my customer.

    This is an obvious Sequential style workflow.  To implement it, I create a Sequential Workflow project, add a sequence of Activities which ask Fred to review, Joe to approve, and finally myself to send the document – and I’m done.

    A Sequential workflow is characterized by the fact that the workflow is in control.  Fred, Joe and I get to do what we’re told, when we’re told to do it.  We do our stuff, let workflow central know that we did it, and then the workflow decides what happens next.

    Of course, the Sequential style doesn’t mean that things always happen in a simple linear sequence like this.  We can have conditional branching, loops, and so on.  What it means is that the workflow controls the sequence.  The Sequential style is the classic style of workflow, as implemented by dozens of products over the years. 

    In my opinion, it is also significantly responsible for giving Workflow a bad name.  Not that there’s anything wrong with telling people what to do (I’m known to indulge in the practice myself, occasionally) – but sometimes it just doesn’t work.

    Let’s look at an example.  Say that I’m testing a product that’s being developed.  When I find a problem, I open a bug, assign it to the guilty developer, then wait confidently for the fix. I want to write a workflow to manage this process.

    So far, this sounds very familiar.  The steps are: tester opens bug, developer fixes bug, tester approves fix.  Just like the simple document review we saw before.

    But this is illusory.  What really happens?  A tester opens a bug, and assign it to Bill.  Bill says, no not me, this is Clive’s, and reassigns the bug to him.  Or Bill says, this tester is not in this case quite correct (or words to that effect), and rejects the bug as nonsense.  Or asks the tester for clarifying information.  Or even, if he’s in a good mood, fixes it and hands it back to the tester.  Or, if the original tester is out, another tester.  Or the tester withdraws an erroneous bug (surely not).  And so on, with each participant being able to make one of a set of choices at any given stage.

    What happens if I write this in the Sequential style?  Something like this (if you’ll forgive my pseudocode):

                   Tester T creates instance of bug workflow
                   T adds bug details
                   T assigns to developer D
    LabelA:     Switch
                         D assigns to developer E
                               Goto LabelA
                         D rejects bug to T:
                               Switch
                                     T accepts rejection:
                                     T updates bug and assigns to developer F:
                                              Goto LabelA
                               End Switch
                         D requests info from T:
                         T submits info
                               Goto LabelA
                         D submits solution to T:
                         T withdraws bug:
                   End Switch

    You get the idea.  Loops and choices which arise within choices are posing structural questions (here I held my nose and used Goto, to try and keep the mapping from the scenario to the code obvious).  And if we start making the process more realistic still, with a queue of bugs coming in that a development team leader assigns to individuals (or a developer might grab them from the queue), and we add a project manager to the picture with the ability to set bug priorities in flight, and so on, things will get worse and worse.

    This problem is much better tackled using the State Machine style.  The pseudo-code above becomes:

    State: Initial
          Action: T adds bug details
          Action: T assigns to developer D; new state = Fixing

    State: Fixing
          Action: D assigns to developer E
          Action: D rejects bug to T; new state = Rejected
          Action: D requests info;  new state = Pending Info
          Action: D submits solution; new state = Pending Approval
          Action: T withdraws bug; new state = Closed

    State: Rejected
          Action: T accepts rejection; new state = Closed
          Action: T updates bug and assigns to developer F; new state = Fixing

    State: Pending Info
          Action: T submits info; new state = Fixing

    State:  Pending Approval
          Action: T rejects solution; new state = Fixing
          Action: T accepts solution; new state = Closed

    State: Closed

    This is much cleaner and more comprehensible.  Also, adding more features will not complicate the structure – it will simply mean adding more states and actions.

    Implementing this style in Windows Workflow Foundation is simply a matter of creating a State Machine Workflow project and defining the states and actions required.

    So what’s the criterion for using the State Machine style?  Simply this: are the important choices being made outside the workflow?  Is the user in control?  If so, then the Sequential workflow’s notion that it calls all the shots will become a nuisance.  The State Machine style of workflow, on the other hand, expects the choice of what to do to be made outside the workflow.

    So if the workflow makes no choices, what is it for?  Well, a State Machine workflow controls the sets of choices.  It makes no sense for a tester to accept a solution until one has been submitted.  It only becomes valid when the bug workflow has reached an appropriate state – by one of a large number of possible routes.

    It’s this last point that leads us to another insight about why the State Machine style is more applicable to this problem.  The Sequential workflow, of its nature, encodes all the possible sequences of behavior in its structure.  But here, we don’t care.  We only need to know about the current state, and what can be done next.  So if we spend time modeling routes through the process, event though we don’t in fact care about them, and these routes are many, as they are in the bug problem, then the Return On Investment from the Sequential style inevitably becomes very poor.

    OK, so far, so good.  What’s this third, Data-Driven, style about?

    This time, we’ll use the example of an inventory shortfall.  An assembly line is making a gadget, and the computer said there were enough widgets in stock for the purpose, but when the stockroom manager went to fetch the widgets, there was a shortfall of 10.

    We want to build a workflow to handle this scenario.

    What are the possible actions?  The supplies department could order more widgets, perhaps going to a different supplier or paying more money for faster delivery.  The account manager could go to the customer and defer delivery, or split the delivery in two parts and bear the extra shipping cost.  The production manager could take assembled gadgets from an order for another customer and divert them.  The stockroom manager could search his stock to find the missing widgets.

    Our workflow will be a collaboration, containing all these actions, restricted to the appropriate roles.  Any given action might be performed multiple times.  One obvious constraint is that the collaboration is not done until the shortfall is fixed by some combination of the above actions.

    There will also be business constraints.  For instance, there may be a rule that says deferral of delivery to gold customers is never permitted.  Also, the actions will affect each other.  For instance, we may say that total added cost from corrective action may not exceed 5% of original factory cost – so placing an order for accelerated supplies might prevent a shipment being split.

    This is not a Sequential workflow – all the decisions are being made outside the workflow.  Is it a State Machine workflow?  Clearly, the sets of actions allowed to each role varies as the collaboration progresses – as splitting shipments becomes impossible, for instance – and the workflow is determining these sets of actions.

    But the set of actions available at any given point is determined by the interaction of a number of  independent rules – whether the customer is a gold customer, whether we have already deferred delivery once, whether the profit margin on the order is becoming a problem, etc.  So the number of possible sets of actions – and therefore the number of corresponding states – is going to be large. 

    Crucially, we’re actually not interested in what these possible combinations of actions are – only that the rules are enforced.  So we find ourselves again in a situation where a modeling approach, in this case the state machine, captures information we don’t care about – and therefore has poor ROI.

    What do we get ROI from modeling?  Why, simply what are the available actions, and who can perform them under what circumstances.  This is just a set of actions, and for each, a role and a boolean expression which determines availability.

    There is one more thing.  We’d like to know when our collaboration is done – so we add to the model another boolean expression which is true when the collaboration is finished.  In this case, the expression will test whether there are, or will be, enough widgets in stock for assembly.

    How is this Data-Driven style implemented in Windows Workflow Foundation?  There are two model elements to support this approach:  the Constrained Activity Group, and the Policy.  Both are typically used within a Sequential Workflow project, and represent regions of ‘data-drivenness’.

    Clearly, it would be possible to model all workflows in this Data-Driven style.  Wouldn’t we then have only one modeling approach to worry about?

    This is true, but not optimal.  To see why, consider how we know that a Data-Driven workflow is correct.  We cannot predict its behavior very easily at all – the number of possible different series of actions that the workflow will allow is very large.  So really the only way to test it is to try it, using enough different initial states, and enough different paths through it, that we feel confident in its operation.

    Contrast the testing of a Sequential style of workflow.  It has only a few possible sequences of behavior, which we can test exhaustively.  We can get a higher level of confidence more cheaply.

    So the motto is, choose the workflow model which has as much structure as your problem has – and no more.  Deviating in either direction costs you money.  Using a style with too much structure adds cost because you’re encoding information which has no value.  Using a style with too little structure adds cost because your testing costs are higher than they need to be.

    And one final word.  Do not think that a typical real world application should use only one style.  Most applications are most cost-effectively built from a composition of styles.  Consider a Call Center application where most of the time the system uses scripts to drive the telephone operators.  Probably a  Sequential workflow.  But then there are always the exceptions, such as an account in a shouldn’t-have-got-there state.  Now we want to refer to an expert.  Experts need to make choices – and so should be supported with a State Machine or Data Driven workflow.

    So there you have it – my thinking on styles of workflow in the Windows Workflow Foundation.  Feedback, as ever, solicited and welcome!

      

     

     

  • An open model

    Well, here I go again.  It seems I must be having fun!  And, I admit, I’m encouraged by the kind words I’ve received so far – for which, thank you.  But let’s hope this doesn’t turn into one of those ‘blog fast, dry young’ affairs.

    Last post, I talked a lot about what a model can do for you.  But I think it’s also important to talk about the proper limits of a model, and what happens at the edges. 

    I’m sure we’ve all had the experience of working with a product which gives access to its wonders through a model of its own invention, but does not really admit of any other world view.  We’re grateful for the value it delivers, but frustrated that we have to dance to an alien tune to add needed behavior that the product doesn’t cover.  Cozy support becomes stifling straitjacket.

    This is why it is important in product design to pay very careful attention to what a product does not do.  This has two aspects: making the design center of the product very clear, so that its use in practice plays to its strengths; and working through a whole series of scenarios in which the product is only part of the solution, to make sure that it can be fitted neatly into a larger jigsaw puzzle.

    We kept these considerations strongly in mind when we were designing the Windows Workflow Foundation.  The design center is simple – make developers more productive when building workflow-enabled applications. With the focus on productive development, we knew from the beginning that we wanted to offer a smooth transition to code wherever the model added no direct value.

    Of course, finding the right balance and transition between model and code was never going to be easy – we tried out quite a few variations over the two years we were working on WWF.  We think we got pretty close in the end.  But now we’re in the hands of the final arbiters – yourselves – and I hope you'll tell us loud and clear how well we really did.

    Another huge factor was that we weren’t building a standalone product, but a part of the Windows platform, the System.Workflow namespace in WinFX.

    That meant very high standards for consistency with the rest of WinFX, approachability, conceptual clarity, naming, and intelligibility.  The WinFX guys (including Brad Abrams and Krzysztof Cwalina) did a great job helping us to get there.  I love the fact that I can show a complete, understandable and working Worfklow host on a single legible slide – less than 10 lines of C# in the Program.cs of a console app.  Just install the  WWF SDK and create a Sequential Workflow Console Application project or a State Machine Console Application project, and you’ll see.

    But perhaps the greater challenge was that the target scenarios are unbounded.  When building a platform, it is a major mistake to imagine that you know everything that you are going to be used for.  In fact, a key success criterion for us is that you, the developer, should be able to use our framework to build things we have never even imagined.

    This meant that any model we came up with could never be definitive.  We could (and did) make it as useful as possible – without core commonality there could never be a viable ecosystem - but we always knew that we needed an open model that you could extend and shape to your own purposes.

    The Windows Workflow Foundation model is open in many ways.  We provide Sequential Flow and State Machine workflows – but you can invent a completely different style of your own, if you wish.  We provide a notion of Sequence within a Workflow – but if you’d prefer one that executes its children in random order, go ahead, that’s fine.  You can build new workflow elements (i.e. Activities) out of old, either by deriving from them or composing them, much as you can build custom controls for a form.  Or you can just go ahead and code some completely new workflow element from scratch.  All the APIs used by the workflow elements that we ship are public and documented.

    Our core aim can be summed up simply – deliver value, then get out of the way.  So, there are two things we would like feedback on.  Firstly, did we deliver the right support, are there important, common things that we missed out?  Secondly and perhaps more importantly, did we succeed in getting out of the way, are there times you have to wriggle around us?

    You can give us your feedback here.  Be sure we will be listening closely.

     

  • What is Workflow, and why bother?

    Workflow, of course, is one of those deeply overloaded terms that hinders communication as often as it helps, so I’d better say what I mean by it.

    Workflow comes down to just two ideas: that there is work to do, which a workflow sees as opaque units of behavior; and flow, which describes what work gets done when.

    So is this a Workflow?

    public void HandleLoanRequest (string customerID, Application app)
    {
        if (CheckCredit(customerId, app.Amount))
        {
            MakeOffer (customerId, app);
        }
    }

    Yes, I believe it is.  The work is checking the customer’s credit and making an offer – and HandleLoanRequest defines if and when this work is performed.

    But the fact that workflow vendors have traditionally felt that something more than this sort of code is required before they declare victory suggests that we’re still missing a key notion.

    This, I believe, is that we don’t just need to describe the flow, but describe it in a way that we can inspect, reason over, and manipulate.  In short, workflow needs a model.

    C# is one way to do this - we can define coding standards that allow us to scan workflow code and draw a graph of the flow, for instance.  Or we could define attributes for the developer to use to call out the parts of his code that form the model.  This is not the choice that we made for the Windows Workflow Foundation – and I’ll talk about why we chose what we did in later posts – but it would work.

    But back to why we might need a model.  We’re going to have to put in effort to create it, so why bother?  Where’s the payback? (or the beef, as this Englishman abroad is learning to call it).

    Well, I think the payback comes from what the model enables -

    Visualization  Useful for the developer, during both development and maintenance, but also for the workflow user who wants to know why they are supposed to be doing what they’ve been asked to do, or the IT Ops guy who wants to know what some misbehaving app is, or should be, up to.

    Expressiveness  A workflow model is a Domain Specific Language, specialized to support characteristic problems.  An example is a review process where three positive votes out of five reviews mean that the document is good – and any outstanding reviews can be canceled.  This is a little tedious to code, but the Windows Workflow Foundation includes out-of-the-box constructions that address such problems.

    Execution  The runtime can exploit the model to take away the need to solve the same problems over and over again.  In the Windows Workflow Foundation we built in support for the knotty problems of long running workflow such as state management and compensation – controlled by simple, expressive model elements.

    Monitoring  The existence of a model makes it possible to produce an event stream with a meaningful semantic without any additional developer effort.  This can then be used to monitor instances of workflows, or aggregates.  Windows Workflow Foundation allows also allows declarative decoration of events with application data pulled from the workflow state - so that you can tell that credit check has started for order 14532.

    Transformation  Models beget models.  An example is the transformation of a workflow model into the Message Exchange Pattern required to communicate with it – as Dharma and Don demonstrated so beautifully at the PDC.  Another is customization.  An ISV ships a workflow, which is customized by a VAR, and then again by a customer.  Then the ISV ships a new base version.  The use of a shared, well understood model for the workflow makes the consequent 3-way merges much more tractable.

    Composition  If an application is factored into flow and work, then the atomic elements of work, with their well understood interfaces, can be reused by other workflows.  Workflows themselves are valid definitions of work that can also be used by other workflows. 

    Customization and transformation together enable ecosystems where definitions of work and flow become shared or traded artifacts.

    Manipulation  Often there are requirements to invent or modify workflows on the fly.  If this means changing code, then there are going to be problems with the security folks – even if the users understand how to hack it.  Using a model makes possible dynamic manipulation that is both controllable and comprehensible.  The Windows Workflow Foundation supports the dynamic modification of both workflow types and workflow instances.

    So that’s it (or at least, all that seeps into my mind this Saturday afternoon).  That’s why we thought a model was a good idea, and why we think it has great ROI.  But if none of these benefits apply in your scenario, then really, coding is still very cool.

  • Blissfully happy at the PDC

    I've spent the last two whole days talking to people about workflow!

    That's one for each of the years I've been working on what the world now knows as the Windows Workflow Foundation.  The release from the pressure of my contractual code of silence has made this PDC just a total blast.

    So now, sitting here in a quieter moment in the Track Lounge, time for the blog - another pleasure I've been promising myself for the longest time.

    What do I want to talk about?  Well, I'm the architect of Windows Workflow Foundation, so I want to tell you all about what we set out to do, and why that led us to the decisions we made about what to put in, and perhaps more importantly what not to put in, and what's it all for, and, and - and, of course, get your feedback.

    But for now, time for another verbal fix....


© 2008 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker