Workflow Tasks, the Replicator activity and State Machines

This post is in a response to a question I saw yet again on the Technet forums today. This question is in no way unusual--in the course of developing SharePoint workflows, many of us eventually ask "how can I fire off a slew of Tasks all at once?" The answer, after some research, is always to use the Replicator activity.

Replicator activity

The Replicator activity can be described as a "foreach loop for workflow." It's not that simple, but the gist of it is: if you have a list of things (let's hypothetically say, SharePoint Workflow Tasks), you can run parallel Workflow threads for each item in the list, without knowing in advance how many items you'll want to replicate. See, I even used the words "for each" in the description.

There are some workflow concepts that don't easily translate to traditional "imperative" languages, at least not in my vocabulary. Read up elsewhere on the Replicator task if you're interested in digging deeper.

ASIDE: If you're researching this topic, I highly recommend you look at the Approval workflow example in the MOSS SDK. I've searched, trust me, and the Approval workflow example is as good as it gets.

So far, so good, right? Unfortunately, there's a twist!

The twist: State Machine Workflows

I'll preface this with a disclaimer: I'm not a Workflow mega-expert (maybe I am by now, but as of 2007-09-19, I have not yet been awarded the "mega" rank). If you, dear reader, happen to know a better solution, by all means leave me a comment.

Back to the twist: you can't replicate SharePoint Workflow Tasks inside of a State Machine Workflow if you need to wire up multiple events. If you want to study that last sentence for a while, feel free; I'll be here waiting...and, we're back!

The specific problem you'll inevitably run into may be found in the collision of the following conflicting requirements:

  • State Machine workflows allow only one event in each state.
  • Replicator activities must be embedded inside a single state.
  • In order to fire off a slew of Tasks, you'll need to embed multiple events inside a single Replicator activity.

Putting these statements together: if you're creating a useful workflow involving Workflow Tasks, you'll require two (or more) events. All these events must go inside a Replicator activity in order to, um, "replicate" them. This Replicator, in turn, must be embedded (and yet cannot be embedded) in a single state in the state machine.

I can't believe you made it this far

Let's sum up with bullet points:

  • PROBLEM: You won't be able to use a Replicator inside a State Machine in many cases, due to limitations of the State Machine enviroment.
  • SOLUTION: Rewrite your workflow as a Sequential Workflow.

Any advice and all alternate solutions are greatly appreciated. Besides idle curiosity, I have encountered this problem myself and would love to keep "my precious" state machine intact. There's still time!

This is neither a SharePoint-only problem, nor a Replicator-only problem

This is a problem you may encounter in many walks of life. Specifically, you may encounter this problem in the many walks of life that involve programming with all of a) multiple events, b) composite activities, and c) state machine workflows.

Ok. What I mean is that you can get in the same "composite activity containing multiple events" trouble with a Conditioned Activity Group, or a Parallel activity, or...actually I'm tapping out here; I've pretty much exhausted my Workflow knowledge with this post. The point is: it's not just Replicators, and it's not just the SharePoint Workflow Task-related activities.

This can happen to you!

Conceptual nonsense: embedded state machines

And while I have no idea what goes into building an extensible workflow engine, may I humblly submit the following suggestion: can we embed state machines inside state machines? While this sounds crazy (AND THIS IDEA IS, IN FACT, CRAZY), allow me a defense:

  • CURRENT BEHAVIOR: Replicators are, in a conceptual sense, kicking off parallel Sequential Workflows. Hosted in a Sequential Workflow, this matches up nicely, as you can easily envision the Replicator activity as a sort of "accordion-style pile of Sequential Workflows--expands or contracts as necessary."  The point is, it fits the Sequential Workflow conceptual model.
  • PROPOSED ALTERNATE BEHAVIOR: StateMachineReplicators could kick off multiple child State Machine Workflows, one state machine for each replication. This "mess of child state machines" would appear to the host as a single state (i.e. the StateMachineReplicator). Inside, you code up your events in separate child states.

    At this point, the word "state" is losing meaning, so I'll try to wrap up:
    • BONUS: You can now embed Replicators (and probably other similar activites, like Conditioned Activity Groups) inside State Machines. AND they'll now be functional enough to be useful!
    • BONUS: You maintain the conceptual integrity (see subtitle for this section) of the State Machine--you still maintain the 'no more than one event on a state' rule.