AppliSec

Manu Cohen Yashar

August 2007 - Posts

Workflow dynamic changes performance

WF dynamic changes are a performance disaster

 

I wanted to build a workflow which has 3 parallel branches that executes continuously

Each branch holds a list of activities.

What is interesting about this workflow is the fact that activities can move from one branch to another.

I found out that whenever an activity moves CPU increases drastically.

I used the following code and found out interesting phenomenon:

1.       Even if there is no change in the workflow (no activities are added nor removed) there is a huge spike in CPU !!!

2.       This is the interesting part: If you continue to perform changes (let us say once a minute an activity is moved) the CPU spike will be greater every time. In my system I created a WF change every few seconds and after few minutes the I experienced 100% CPU spikes!!!

This is amazing!!! It means that someone did not release resources …

It is expectable that one operation influences another one.

Let us see some code:

 

// 1. Create a WorkflowChanges class to author dynamic change

changes = new WorkflowChanges(this);

            CompositeActivity ActiveTestsComposite = changes.TransientWorkflow.GetActivityByName("ActiveTestsActivities") as CompositeActivity;

 

 //2. Add the activities to the branch (they all inherit from TestBase)

 foreach (TestBase test in TestsToAdd)

 {

         //we want to create the exact type of test.

         TestBase NewTest = Activator.CreateInstance(test.GetType()) as TestBase;

         . . .

         ActiveTestsComposite.Activities.Add(NewTest);

         test.Dispose();

         AddFlag = true;

 }

 // 3. Remove the activities to remove

 foreach (TestBase test in TestsToRemove)

 {

         ActiveTestsComposite.Activities.RemoveAll(delegate(Activity tst)
         { return ((tst as TestBase).TestName == test.TestName); });

         removeFlag = true;

}

 

try

   {

    // 4. apply transient changes to instance – Here CPU just booms

    this.ApplyWorkflowChanges(changes);

   }

catch (WorkflowValidationFailedException ex) { ... }     

               

 

 

So the result is:

 

1.       Never use Workflow dynamic changes capabilities repeatedly

2.       Try to avoid WF dynamic changes  - They cost too much.

 

What was my solution you ask?

 

I created an activity that read a list of objects (in our case activities) and call their execute method.

These lists can be easily handled like a normal collection.

In each branch I put one such activity and dynamically changed the lists.

Now the Workflow stays the same. No CPU spikes.

 

We are talking about a major bug (I tried this in VS 2008 Beta 2) and it was not fixed. Maybe someone will read this and. . .

 

Manu Cohen-Yashar