Tuesday, February 2, 2010

Hi all

Lots of people think, that if they use a Parallel Actions shape, they get things done in parallel. Well, rethink that. An orchestration executes in just one thread, so no chance of getting anything to run in parallel. At runtime, the shapes in the parallel shape are simply serialized.

But what is the algorithm, then?

Well, I did some tests. First of all, I created this simple orchestration:


It’s a receive shape to fire up the orchestration and then a parallel shape with four branches and five expression shapes in each. The code in each expression shape is this:

   1: System.Diagnostics.Trace.WriteLine("X. Y");

where X is a number indicating the branch and Y is a sequence number within the branch. This means that X=2 and Y=3 is the third expression shape in the second branch and X=4 and Y=1 is the first expression shape in the fourth branch.

Running this orchestration I get this result from DebugView:


So as you can see, the entire first branch is executed, then the entire second branch, and so on until the fourth branch has finished. Sounds easy enough. But lets try some other scenarios like this one:


In essence I have thrown in a receive shape in branch 2 to see if branches three and four will still have to wait until branch 2 has finished.

The result can be seen here:


So as you can see, the second branch stops after the second shape because now it awaits the receive shape. Branches three and four are then executed and after I send in a message for the receive shape, the second branch completes.

So some form of parallelism is actually achieved, but only when a shape takes too long to handle. Lets see what happens with a Delay shape instead like this:


I have switched the Receive Shape for a Delay shape, and I have set the Delay shape to wait for 100 milliseconds. The result of this is the same as with the Receive shape:


Then I tried setting the Delay shape to just 1 millisecond, but this gave the same result.

With shapes that take time in two branches, like this:


And the Delay is still set at one millisecond. I get the following result:


So as you can see, the Receive shape causes branch 2 to stop executing, and the Delay shape causes branch 3 to stop executing, allowing branch 4 to execute. Branch 3 is then executed because the Delay shape has finished and finally once the message for the Receive shape has arrived, branch 2 is executed to its end.

Another thing to note is, that the Delay shape actually doesn’t make the thread sleep. If it did, we couldn’t continue in another branch once a Delay shape is run. This makes perfectly sense, since the shapes in one branch are to be seen as a mini-process within the big process, and the delay that is needed for that mini-process shouldn’t affect the other branches. This is exemplified in this process:


The third expression shape in the first branch has been updated to this code:

   1: System.Diagnostics.Trace.WriteLine("1. 3");
   2: System.Threading.Thread.Sleep(2000);



So as you can see, even though the first branch must wait for 2 seconds, it still executes completely before the second branch is started.

So, takeaways:

  1. The Parallel Actions shape does NOT mean you get any multi-threading execution environment.
  2. Think of the PArallel Actions shape as a way of letting multiple Business Activities happen and you don’t know in what order they will occur.
  3. The Delay shape does not use Thread.Sleep, but instead handles things internally.


Tuesday, February 2, 2010 8:27:56 PM (Romance Standard Time, UTC+01:00)  #    Comments [6]  | 
Wednesday, February 3, 2010 2:37:24 AM (Romance Standard Time, UTC+01:00)
Nice indepth look at this often misunderstood shape.
What parallel shapes are great at doing is ensuring that all sub-branches have completed before further processing on the main branch continues.
Wednesday, February 3, 2010 7:28:25 AM (Romance Standard Time, UTC+01:00)
Thans, Ryan.

You are right about what the parallel action also gives us, but that is also achievable using plain serial orchestrations.

As I see it, the main advantage (and really the only real usage) of the parallel actions shape is, that you get to receive messages in any order.

Wednesday, February 3, 2010 3:18:09 PM (Romance Standard Time, UTC+01:00)
Jan, I'm not convinced that your basic premise is correct. It has always been the case, even with BTS 2004, that simple tests of single orchestrations generally result in all branches of a parallel shape being executed on a single thread. BizTalk certainly does not allow run-away thread creation (imagine what would happen in a naive implementation if you had 100 in-flight orchestration instances, each one with 10 parallel branches). However, to infer from this that the parallel shape is always single-threaded is not necessarily so. My understanding was that BizTalk schedules execution of parallel branches and that under load it may well execute different branches on different threads. Indeed, I'm fairly certain I recall seeing direct evidence of this behaviour, but I forget which version of BTS I was using.

I did a quick Bing/Google (should that be a Bingle?) as a sanity check - and found totally conflicting statements about BTS 2006. Based on what Darren Jefford wrote in Professional BizTalk Server 2006, Yossi Dahan suggests that BizTalk 2006 may have different behaviour to BizTalk 2004. I don't know for sure if this true. Jason Hyland suggests that BTS 2006 (and I expect, by extension, BTS 2009) can use multiple threads is different circumstances. I don't know the answer for sure, but careful testing under significant load with lots of orchestration instances containing some brief delays in parallel branches would probably provide good evidence of the truth. For the time being, I would still advocate writing thread-safe custom code if you intend to invoke that code in a parallel branch.
Thursday, February 4, 2010 7:38:14 AM (Romance Standard Time, UTC+01:00)
Hi Jan, Charles

I'm pretty surea that the behaviour has changed in 2006 (and on..) and fairly certain threads will no longer be created, as discussed on http://www.sabratech.co.uk/blogs/yossidahan/2009/07/parallel-shape-behaviour-in-biztalk.html

I've had some conversations with various people at the time that seem to have confirmed the 'educated guess'.

Wednesday, July 7, 2010 12:09:24 PM (Romance Daylight Time, UTC+02:00)
Orchestration parallel shape (and listen shape) give parallel view to end-user. In reality, code belonging to different branches is always executed on single thread. Once orchestration engine has started executing a branch (B1) belonging to an orchestration instance, it won’t execute another branch(B2) for same orch instance, till :
1. B1 finishes, or
2. B1 yield control to orchestration engine scheduler. This yield can happen in two ways:
a. B1 calls Receive
b. B1 calls Delay.
At this point the B1 is marked as in wait state and it remains in this state till the condition to remove it from wait state is satisfied. This condition could be expiry of delay or arrival of message matching the receive shape. After that B1 is put back in the scheduler Queue where it waits for the turn. Orchestration engine scheduler is co-operative scheduler as orchestration code explicitly need to tell if it is going it wait state.

Historically BizTalk tried multithreaded execution of parallel branches but this implementation didn't live long. Recent BizTalk releases (2006 onwards) just follow what I described above.
Wednesday, July 7, 2010 8:14:08 PM (Romance Daylight Time, UTC+02:00)
Hi Anil

Thanks for clarifying this. Nice to get some closure on a discussion! :-)

All comments require the approval of the site owner before being displayed.
Please login with either your OpenID above, or your details below.
Home page

Comment (Some html is allowed: a@href@title, b, blockquote@cite, em, i, strike, strong, sub, sup, u) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview

Theme design by Jelle Druyts