Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Replay Failed Workflow

0.00/5 (No votes)
25 Mar 2013CPOL3 min read 7.3K   1  
Knowledge sharing article on WWF.

Introduction 

Here in this article I am going to provide the solution on how to replay faulted sequential workflow if that was terminated in between before completing all the activity successful. And the main focus to article is to replay the workflow from the activity it was faulted and continue executing rest other activity as BAU. Why I came to this solution because, I am seeing this problem since long time in my project, and every time manual work was required to complete the Orchestration of the workflow.

In my previous article I had provided the solution of re-playing the activity in workflow. And here how to re-play the workflow. Both are two different concept and different requirement as per our need.  

Background

Idea behind this solution is to provide advance replay functionality to our Orchestration system, built on Windows workflow foundation. Suppose you have many sets of activity in your workflow and each activity do some write/update/calculation/etc with data in its respective activity. And in some case one of the activity get faulted and terminates the workflow. Now, in this scenario we can't replay the workflow from start, because it will/may execute same activity which was already completed before. Basically we want replay to happen from the point where it was faulted. 

Basic Understanding 

Before I approach to solution to the problem. Let me explain the basics of WWF and we will try to find the solution in its basic understanding. 

As we know WorkflowRuntime is used to create workflow in run-time.  

C#
WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication1.Workflow1));   

CreateWorkflow gives the WorkflowInstace which load the complete workflow in the memory thread.

C#
instance.Start();  

And we tell workflow to start executing each activity one by one.

There is a class WorkflowChanges which can we used during run time to make any changes in workflow. 

Preparing strategy for solution

  1. You should have logging mechanism in your workflow application using workflow tracking service
  2. You should log each activity state, so that you know due which activity faulting your workflow got terminated
  3. At time of replay of workflow you should know the name of activity from where you want to replay the workflow. 

Once you have above functionality in your application, now i can proceed explaining other bit required for replay.

  1. Create the workflow instance  
  2. Access the workflow inside WorkflowInstace  
  3. Initiate WorkflowChanges object for your original workflow
  4. Workflow change object will load your original workflow in TransientWorkflow 
  5. Now loop in all activities inside TransientWorkflow and remove all activities which already executed before and leave all those activity requires to execute.  
  6. Now apply the  WorkflowChanges  to orginal  WorkflowInstace 
  7. Then start the  WorkflowInstace 
  8. Done you have made required change which need to replay. 

Using the code

This is the workflow in my sample POC project. And i am assuming my workflow got terminated at ReplayfromThisActivity Activity in this below workflow.

 

Now, Let see how this code will look like as per our requirement to replay the workflow from the faulted activity and skip activities which already executed.     

C#
var workflowRoot = (Workflow1)instance.GetWorkflowDefinition();
WorkflowChanges changes = new WorkflowChanges(workflowRoot);            
System.Collections.Generic.List<Activity> exectuedActivities = 
          new System.Collections.Generic.List<Activity>();
foreach (Activity childActivity in changes.TransientWorkflow.Activities)
{
    //
    //Here i am comparing the activity name from where workflow should execute
    //
    if (string.Compare(childActivity.Name, "ReplayfromThisActivity") == 0)
    {
        break;
    }
    exectuedActivities.Add(childActivity);
}
//
// Removing all activities which already executed before
//

if (exectuedActivities.Count > 0)
{
    exectuedActivities.ForEach(childActivty =>
        {
            changes.TransientWorkflow.Activities.Remove(childActivty);
        });
}

//
// Apply transient changes to instance.
//
instance.ApplyWorkflowChanges(changes);

As you can see in this code I have followed all my steps which i have pointed above. To skip executing activity, I have removed those activities from the workflow and kept rest other as it is, so that when workflow start executing the 1st activity it will get to execute is the activity from where I wanted to replay the workflow. 

That all in this article, hope this will help you.  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)