A few weeks ago I came across an issue involving a Workflow Join Activity and some confusion around what it does and how it works. There is a little bit of documentation on the wiki but it still left some questions unanswered.
The purpose of the Join Activity is to combine two or more paths of execution after they have branched out. This serves the purpose of ensuring that subsequent activities will not get run multiple times with unexpected results.
A Join activity will always wait for all active paths of execution to reach it before proceeding.
The difference between the Complete and Incomplete outputs comes down to whether or not all possible paths of execution have completed. For example, if there is a split to have two simultaneous tasks on parallel paths then after both tasks have completed the Join will finish with Complete.
To contrast that, when there is an if statement, only one path will ever actually get executed so the Join will always exit as Incomplete.
Hopefully that clarifies things a bit for you; it certainly helped me to review how it worked.
The statement “A Join activity will always wait for all active paths of execution to reach it before proceeding” is not entirely true. In fact, a Join activity will also wait for all active activities to complete as well, even if they are not in the actual branch-join path.
This was a head scratcher for us a few months back, so I thought I would share so others are aware.
I’m not sure I quite follow what you’re getting at. I’ve had paths that went around Joins and the Join waits only for those activities that have transitions that lead into it.
That’s a very powerful concept, I like that a lot! you can set up some very complex workflows with that. that’s for sharing James.
So in the case of an if statement with two POTENTIAL paths before the join, will the join return Incomplete after all active paths have terminated? I ask because I have a stakeholder that wants to manually launch 1 – 5 tasks at the end of a workflow. I only want to end the workflow when all of the 1-5 tasks are closed, but the number will never be consistent.
Yes, that’s exactly how it works. With the scenario of 1-5 paths, if there are 5 total potential paths and all 5 get executed then the Join would exit as Complete after they were all done. If 1-4 paths are executed then when all the activities that needed to run have completed the Join will exit as Incomplete.
In almost all cases you’re going to want to have both output lines going into the same activity afterwards. The only reason they would go to separate activities is if you wanted to differentiate between some or all of the potential paths of execution.
There are other options than a Join activity that may work better for you in the case you’ve quoted. If the client is manually adding tasks to a workflow, you can use a Wait for Condition activity to wait until all tasks are completed before moving onto the next step. If you go this route you’ll also need to accompany it with a business rule on the table against which the workflow is running. The Wiki has a useful example of how to configure both the Wait for Condition activity and the business rule:
Go to section 4.4 of this article for all the details.
What confused me about Join seems to be a result of the definition of “path”. I assumed that the reason for Branch was to define the paths which one way or another must meet at the Join that is waiting for their completion. Now, the examples above don’t use Branch. But they explain Join as waiting for all paths to complete. I think that pins down the problem I have been having.
My moderately complex workflow that has a 3-way Branch, and some branches have If alternatives and conditional tasks, so that by the time the Join is reached there are 9 possible paths into the Join. Needless to say it always exits Incomplete. Not the behavior I expected, as every one of the 3 branching paths DID complete! But of course, both alternatives of every If NEVER complete.
Understanding this, I’ll send the Complete and Incomplete paths out of Joins to the same place from now on. However, that raises a question: If the Join gets 3 of the 9 inputs and correctly moves forward via the Incomplete path, is there a chance that it will sometimes incorrectly move forward with only 1 or 2 of the 9 inputs??
Right, the Branch activity doesn’t actually do anything different than just having the paths go out to multiple activities from any other activity.
There isn’t any way for it to move on from the Join if there are still active paths leading up to it.