The mysteries of software development and networking... RSS 2.0



 Wednesday, April 09, 2008

Background: Assume we have workflow which is hosted as a WCF service. Every workflow instance is identified by the workflow instanceId. When a remote call comes into the workflow runtime the runtime needs to identify which workflow instance the caller wants to communicate with. If no identification is provided the runtime will assume a new workflow instance needs to be created.

Consider the following piece of client side code which calls a workflow service called FirstOperation() which is handled by a ReceiveActivity on the server:

ClientProxy proxy = new ClientProxy();
proxy.Open();
proxy.FirstOperation(); //creates a new workflow
proxy.Close();

Now assume a second call needs to be made and the second call needs to be handled by the same workflow because in this workflow there is second ReceiveActivity waiting for the SecondOperation to be called.
The following piece of code will do just that:

ClientProxy proxy = new ClientProxy();
proxy.Open();
proxy.FirstOperation(); //creates a new workflow
//.. more code, keep the WCF channel open
proxy.SecondOperation();
proxy.Close();

The above code will work because the ReceiveActivity in combination with the WorkflowServiceHost automatically adds information to the WCF context. The instanceId of the workflow has been added to the context. The above code is bad design. The connection to the server is a valuable resource and should be closed as soon as possible. The following code snippet show how the context manager is used to retrieve the context from the call which initiates the workflow and is then reused when a new client proxy is created.

ClientProxy proxy = new ClientProxy();
proxy.Open();
proxy.FirstOperation(); //creates a new workflow
IContextManager manager = proxy.InnerChannel.GetProperty();
IDictionary context = manager.GetContext();
proxy.Close();

//.. more code, the WCF channel is now closed

proxy = new ClientProxy();
IContextManager manager = proxy.InnerChannel.GetProperty();
manager.SetContext(context);
proxy.SecondOperation();
proxy.Close();

The IContextManager has been added in .NET 3.5 to help with correlation. The code needed in .NET 3.0 to achieve the similar functionality is much less elegant.

Note 1: Server side both the ReceiveActivity as well as the SendActivity have a Context property allowing for easy access to the context. A common pattern for implementing a callback is to set the context of the SendActivity to the value of the context of the ReceiveActivity. In the scenario illustrated above the context would consist of just the instanceId. In scenarios where the workflow is using send and receive activities within a parallel activity the context will automatically get extended to include a conversationId, allowing the WorkflowServiceHost to correlate an incoming call to the correct receive activity.

Note 2: If you want manually add the instanceId to a context, have a look at this post by Maurice de Beijer.


Wednesday, April 09, 2008 1:59:06 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
WF
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: a@href@title, strike) 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
About
This blog is run by Mark Blomsma.
© Copyright 2008
Develop-One
Sign In
Statistics
Total Posts: 305
This Year: 49
This Month: 2
This Week: 1
Comments: 36
All Content © 2008, Develop-One
DasBlog theme 'Business' created by Christoph De Baene (delarou)