In the case of a server unscheduled shutdown, in the database, there can appear processes stuck in the Running status. This is the only process status that blocks any other operations with the process. The recovery procedure finds such processes and resets their statuses to Error or Terminated.
The Error status means that the process can be changed with command triggered transitions or timer triggered transitions. Thus, the process does not hang in this state, and you can work with it as before.
The Terminated status means that the process has no exit either by command or by timer. Thus, you can restore the execution of this
process, for example, using the
workflowRuntime.SetState() method. That is, such a process requires attention.
The recovery does not differ, whether in the single-server mode or the multi-server mode. In the single-server mode, each process with the Running status is restored after the server is restarted; in the multi-server mode, only those processes are restored, whose Running status was set by the runtime selected for the recovery.
The Error and Terminated statuses are set automatically and does not require configuring.
Recovery of Timers
Timers are not subjects to recovery, because they will always be processed if at least one server is running.
Customization of Recovery Procedure
You should write Process Restorer, implementing the
IProcessRestorer interface to customize the recovery procedure after a shutdown:
public interface IProcessRestorer
bool NeedCustomRestore(string schemeCode, ProcessStatus status);
RestoreDecision GetCustomRestoreDecision(ProcessInstance process);
Let us consider its methods.
NeedCustomRestore- should return true if the custom recovery procedure is necessary.
statuspassed to it is either Error or Terminated, automatically set for the process on recovery.
schemeCodeis the process scheme code. If the method returns true, then the
GetCustomRestoreDecisionmethod will be called for each process to be restored.
GetCustomRestoreDecision- Process Instance is passed to the method, containing all the information about the process; in the result, the method returns the decision of what to do next with this process. The following decisions are possible:
return RestoreDecision.Delete- delete the process.
return RestoreDecision.RunFromCurrentActivity- restart the process with the previous Activity. Please, note that in the case of a failure, the running Activity has not been fixed yet, so the process will start with the previous Activity. That is all right. Read about the process execution here.
return RestoreDecision.RunFromNewActivity(activityDefinition)- start the process with a new Activity,
activityDefinitionis an element of the process scheme.
return RestoreDecision.Default- apply the default recovery mechanism, that is, set either Error or Terminated status.
RestoreDecision, you can change the process parameters, which is a powerful tool to manage the process execution.
For example, your Process Restorer can look as follows:
private class YourCustomProcessRestorer : IProcessRestorer
public bool NeedCustomRestore(string schemeCode, ProcessStatus status)
return schemeCode == "SomeSchemeCode" && status == ProcessStatus.Terminated;
public RestoreDecision GetCustomRestoreDecision(ProcessInstance process)
.RunFromNewActivity(process.ProcessScheme.InitialActivity) // set to Initial Activity
.AddPersistentParameter("wasFailed", true); // the sign that the process was failed
After creating our customized Process Restorer, we should connect it to Workflow Runtime.
var runtime = new WorkflowRuntime()
.AsSingleServer(); // .AsMultiServer();
Any number of Process Restorer instances can be connected to one runtime. The one, whose
NeedCustomRestore method returns
true for the
process selected for recovery, will be used.
Please, note that Process Restorer is only used in the case of a server shutdown. For the workflow errors, use the OnWorkflowError event handler.