Tuesday, September 6, 2011

DevExpress Workflow Instance Store

In version 11.1.7 our team now provides workflow instance support outside XAF borders! With a few lines of code, it is now possible to store our workflows in any of the 14 database systems described in this post.

Durability is a key benefit of the Workflow Foundation and it is based on the ability to store a running workflow instance on the fly at almost any time. 
To this end Microsoft workflow team implemented the SqlWokflowInstanceStore class. Using this class and a few lines is possible to store workflow instances in SQL Server as shown,

// Define SqlWorkflowInstanceStoreBehavior:

//   Set interval to renew instance lock to 5 seconds.

//   Set interval to check for runnable instances to 2 seconds.

//   Instance Store does not keep instances after it is completed.

//   Select exponential back-off algorithm when retrying to load a locked instance.

//   Instance state information is compressed using the GZip compressing algorithm.

SqlWorkflowInstanceStoreBehavior instanceStoreBehavior = new SqlWorkflowInstanceStoreBehavior(connectionString);

instanceStoreBehavior.HostLockRenewalPeriod = new TimeSpan(0, 0, 5);

instanceStoreBehavior.RunnableInstancesDetectionPeriod = new TimeSpan(0, 0, 2);

instanceStoreBehavior.InstanceCompletionAction = InstanceCompletionAction.DeleteAll;

instanceStoreBehavior.InstanceLockedExceptionAction = InstanceLockedExceptionAction.AggressiveRetry;

instanceStoreBehavior.InstanceEncodingOption = InstanceEncodingOption.GZip;

host.Description.Behaviors.Add(instanceStoreBehavior);

The above code was copied from the "BuiltInConfiguration" demo, "InstanceStore1" project. This demo is described at "Built-in Configuration"
(
http://msdn.microsoft.com/en-us/library/ee622978.aspx). You can download full sources of this demo and many others at "WCF and WF Samples for .NET Framework 4"
(
http://www.microsoft.com/download/en/details.aspx?id=21459).

Following the same architecture our team implemented the DX WorkFlow Instance Store. eXpress Persistent Objects (XPO) is used for common objects storage and is fully capable of working transparently with 14 different database systems. For example to provide support for an Oracle database we could write,

//We create or connect to a database by setting the connectionstring

//This code will create 2 tables (XpoWorkflowInstance, XpoInstanceKeyc) in the database

using (var session = new Session()) {

    session.ConnectionString = "Data Source=DevExpressInstanceStore;User Id=myUsername;Password=myPassword";

    session.UpdateSchema(typeof(XpoWorkflowInstance), typeof(XpoInstanceKey));

    session.CreateObjectTypeRecords(typeof(XpoWorkflowInstance), typeof(XpoInstanceKey));

}

 

// Define WorkflowInstanceStoreBehavior:

var dxInstanceStoreBehavior = new WorkflowInstanceStoreBehavior(

    typeof(XpoWorkflowInstance), typeof(XpoInstanceKey), DevExpressConnectionString);

host.Description.Behaviors.Add(dxInstanceStoreBehavior);

dxInstanceStoreBehavior.RunnableInstancesDetectionPeriod = new TimeSpan(0, 0, 2);

dxInstanceStoreBehavior.InstanceCompletionAction = InstanceCompletionAction.DeleteAll;

 

You can download a modified version of the “BuiltInConfiguration” solution here. The console application starts a long running workflow that implements a counting service. Once the service’s start method is invoked, the service counts from 0 to 59. The counter is incremented every 2 seconds. After each count the workflow persists so you can close the application at any time and when you start it next time it will continue. A new one will be started from '0' value in addition to the loaded instances. The second project “InstanceStore2” in the solution provides the same functionality, however it is configured using the app.config file as shown,

<system.serviceModel>

  <extensions>

    <behaviorExtensions>

      <add name="DevExpressWorkflowInstanceStore" type="DevExpress.Workflow.Store.WorkflowInstanceStoreElement, DevExpress.Workflow.Activities.v11.1"/>

    </behaviorExtensions>

  </extensions>

  <services>

    <service name="CountingWorkflow" behaviorConfiguration="">

    </service>

  </services>

  <behaviors>

    <serviceBehaviors>

      <behavior name="">

        <!--<sqlWorkflowInstanceStore

          connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=InstanceStore;Integrated Security=True;Asynchronous Processing=True"

          hostLockRenewalPeriod="00:00:05" runnableInstancesDetectionPeriod="00:00:02" instanceCompletionAction="DeleteAll"

          instanceLockedExceptionAction="AggressiveRetry" instanceEncodingOption="GZip"

          />-->

        <DevExpressWorkflowInstanceStore

          connectionString="Data Source=DevExpressInstanceStore;User Id=myUsername;Password=myPassword"

          runnableInstancesDetectionPeriod="00:00:02" instanceCompletionAction="DeleteAll"/>

      </behavior>

    </serviceBehaviors>

  </behaviors>

</system.serviceModel>

Note; All we need to do to use these code snippets in our code is to reference 'DevExpress.ExpressApp.v11.1.dll' and 'DevExpress.Workflow.Activities.v11.1.dl assemblies. Even though these assemblies are part of our eXpressApp framework they can also be used to support any other type of .NET application!

 

We are waiting to read your feedback about this. Remember that your questions are the best candidates for future posts.

Related Links
Blog posts
Online documentation
Videos

 

 

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

0 comments:

Post a Comment