Ordered Workflow Activation in (SharePoint) Workflow Manager

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

Imaging you are receiving some events which have to be used to activate new workflow instance Wi of some workflow type W.
As long the workflow completes faster than new events arrives, successive workflow activation will execute ordered. That means for each event Ek, workflow instance Wk will be activated in the same order as events arrive. However, sometimes you expect ordered execution of workflows by design. That means next instance of the same workflow must not be started until the previous one has completed successfully.

image 

Technical Design

Due asynchronous activation on Service Bus, you are not in control of activation of specific instance. So, to make asynchronous thing synchron is not easy task. This blog post describes one of more or less solutions which do not require any additional service or similar artifact.

To make this working, implement your workflow in XAML. Then create new workflow (see blue shape below) and paste all activities from your workflow in the new workflow (black frame on picture below).

image

The circle on top of the workflow is the part which you have to implement. That part of workflow will guarantee the ordered execution. We will pump activation messages in the Service Bus queue as they arrive and Workflow will execute them in the received sequence. Following picture shows more details. If the workflow instance ( the only running instance) fails during execution Service Bus will automatically retry failed message when workflow is resurrected.
This is because Workflow Manager receives messages by “Peek And Lock” . If the workflow fails the message will be abandoned 10 times. This means workflow can fail up to 10 times!! This is default behavior which can be changed by manipulating the topic.

image

 

How to create Workflow which receive notifications?

The blue shape on the picture above can be implemented as follows:
image

Notice following 3 activities:

  1. BuildMatchAllFilter
  2. Subscribe
  3. ReceiveNotification

BuildMatchAllFilter is the activity which is usually used by publishing of the workflow. It defines the message which will activate the workflow.
Following code shows how this works:

                client.PublishWorkflow(wf.Name, wf.Name
                new MatchAllSubscriptionFilter()
                    {
                        Matches = 
                       
                            {"RunWorkflow", Ordered”} 
                        }
                    });

The designer equivalent of the same code looks like shown below:

image 

MatchFilter must first define the messages, which will activate it. The definition of this filter is then saved in the variable SubscriptionHandle.
As next Subscribe Activity must be configured.

When executed the SubscribeActivity practically creates the subscription on the Workflow Topic and appends the Rule defined by the filter.
Exact description of this is behind scope of this article, but Service Bus folks will understand what this could mean.


image

The last important activity in this scenario is ReceiveNotificationActivity. In the world of AppFabric this would be ReceiveActivity, which listens on SOAP messages.
in contrast to ReceiveActivity, ReceiveNotificationActivity listens for messages on the topic subscription.

By configuring of this activity, you can leave Properties empty if you work with filter and subscription handle as we do in this case.
To receive the message you have two options:

- To use filter or
- To use SubscriptionHandle

You cannot use both!

If you use Filter, then ReceiveNotificationActivity will receive message and immediately remove the subscription from topic. In workflow like our one when ReceiveNotification is inside of the loop is using of filter (as property of ReceiveNotification) no-go!
Why? Assume some client is sending lot of messages which have to be processed. This is exactly scenario which we are describing in this article. In this case, the message will be received and subscription removed.
As long the workflow activities are executing business logic after the message is received, all upcoming messages will not be delivered to subscription, because subscription does not exist at all (remember, it is removed after receive). Practically you will loose messages.
To fix this you have option to leave Filter property empty (like in picture below) and to set SubscriptionHandle. As long this handle instance exists, subscription exists and messages are delivered to it. hat mean they ill remain inthere as long the business logic is executing.

 

image
The logic which I used to approve this scenario looks like shown below:
image

I have counted and persisted all incoming messages in several scenarios to approve this. The best way to see this in action is to put Delay activity to slows down the processing logic while
activation messages are pumped in. Following code snippet shows how this work.
After all messages are sent, attach to Workflow Host process and investigate how all messages are processed.

            x = 1000;
           
while (x > 0)
            {
            
   var res = client.PublishNotification(new WorkflowNotification()
                {
                    Properties =
                            {
                                {
"RunWorkflow", "Ordered" }
                            },
                    Content =
new Dictionary<string, object>()
                            {
                                {
"Arg1", x.ToString() },
                                {
"Arg2", new Random().Next() }
                            }
                });

               
Trace.WriteLine(res);

               
Thread.Sleep(0);

                x--;
            }

 

image

 



 


Posted Jun 11 2013, 08:18 PM by Damir Dobric
developers.de is a .Net Community Blog powered by daenet GmbH.