void IDisposable.Dispose() { if (this.currentActivity != null) { if (this.contextManager != null) { this.contextManager.Dispose(); this.contextManager = null; } this.currentActivity = null; } }
private static void CollectCompensatableCompletedContexts(ActivityExecutionContext context, Activity targetActivity, SortedDictionary <int, CompensationInfo> sortedListOfCompensatableTargets, bool immediateCompensation) { ActivityExecutionContextManager executionContextManager = context.ExecutionContextManager; for (int i = executionContextManager.CompletedExecutionContexts.Count - 1; i >= 0; i--) { ActivityExecutionContextInfo targetExecutionInfo = executionContextManager.CompletedExecutionContexts[i]; if (((byte)(targetExecutionInfo.Flags & PersistFlags.NeedsCompensation)) != 0) { Activity activityByName = targetActivity.GetActivityByName(targetExecutionInfo.ActivityQualifiedName, true); if ((activityByName != null) && (!immediateCompensation || !IsActivityInBackWorkBranch(targetActivity, activityByName))) { sortedListOfCompensatableTargets.Add(targetExecutionInfo.CompletedOrderId, new CompensationInfo(targetExecutionInfo, executionContextManager)); } } } }
private ActivityExecutionStatus CompensateTargetActivity(ActivityExecutionContext context) { Activity activityByName = null; Activity activity2 = context.Activity; do { activityByName = activity2.Parent.GetActivityByName(this.TargetActivityName, true); }while (activityByName == null); if (((activityByName is ICompensatableActivity) && (activityByName.ExecutionStatus == ActivityExecutionStatus.Closed)) && (activityByName.ExecutionResult == ActivityExecutionResult.Succeeded)) { activityByName.RegisterForStatusChange(Activity.ClosedEvent, this); context.CompensateActivity(activityByName); return(context.Activity.ExecutionStatus); } if (activityByName.ExecutionStatus == ActivityExecutionStatus.Initialized) { ActivityExecutionContextManager executionContextManager = context.ExecutionContextManager; foreach (ActivityExecutionContext context2 in executionContextManager.ExecutionContexts) { if ((activityByName.GetActivityByName(context2.Activity.QualifiedName, true) != null) && (((context2.Activity.ExecutionStatus == ActivityExecutionStatus.Compensating) || (context2.Activity.ExecutionStatus == ActivityExecutionStatus.Faulting)) || (context2.Activity.ExecutionStatus == ActivityExecutionStatus.Canceling))) { return(context.Activity.ExecutionStatus); } } for (int i = executionContextManager.CompletedExecutionContexts.Count - 1; i >= 0; i--) { ActivityExecutionContextInfo contextInfo = executionContextManager.CompletedExecutionContexts[i]; if (((byte)(contextInfo.Flags & PersistFlags.NeedsCompensation)) != 0) { ActivityExecutionContext context3 = executionContextManager.DiscardPersistedExecutionContext(contextInfo); if (context3.Activity is ICompensatableActivity) { context3.Activity.RegisterForStatusChange(Activity.ClosedEvent, this); context3.CompensateActivity(context3.Activity); } return(context.Activity.ExecutionStatus); } } } else if (CompensationUtils.TryCompensateLastCompletedChildActivity(context, activityByName, this)) { return(context.Activity.ExecutionStatus); } return(ActivityExecutionStatus.Closed); }
// walk through active contexts that contain compensatable child, add them in the sorted order of the completion // this also, walks through the completed contexts which are compensatable and are nested directly within the active contexts and adds them in the order of their completion // bail out if any activity is currently compensating/faulting or cancelling private static bool CollectCompensatableActiveContexts(ActivityExecutionContext context, Activity targetActivity, SortedDictionary <int, CompensationInfo> sortedListOfCompensatableTargets, bool immediateCompensation) { ActivityExecutionContextManager contextManager = context.ExecutionContextManager; foreach (ActivityExecutionContext activeContext in contextManager.ExecutionContexts) { if (targetActivity.GetActivityByName(activeContext.Activity.QualifiedName, true) != null) { //Dont walk context which are part of reverse work. if (immediateCompensation && IsActivityInBackWorkBranch(targetActivity, activeContext.Activity)) { continue; } if (activeContext.Activity is ICompensatableActivity && (activeContext.Activity.ExecutionStatus == ActivityExecutionStatus.Compensating || activeContext.Activity.ExecutionStatus == ActivityExecutionStatus.Faulting || activeContext.Activity.ExecutionStatus == ActivityExecutionStatus.Canceling)) { return(true); } else if (activeContext.Activity is CompositeActivity) { Activity[] activities = GetCompensatableChildren(activeContext.Activity as CompositeActivity); if (activities != null) { int lastcompletedContextOrderId = 0; foreach (Activity childActivity in activities) { int completedOrderId = (int)childActivity.GetValue(Activity.CompletedOrderIdProperty); if (lastcompletedContextOrderId < completedOrderId) { lastcompletedContextOrderId = completedOrderId; } } if (lastcompletedContextOrderId != 0) { sortedListOfCompensatableTargets.Add(lastcompletedContextOrderId, new CompensationInfo(activeContext)); } } CollectCompensatableActiveContexts(activeContext, targetActivity, sortedListOfCompensatableTargets, immediateCompensation); CollectCompensatableCompletedContexts(activeContext, targetActivity, sortedListOfCompensatableTargets, immediateCompensation); } } } return(false); }
// walk through all completed execution contexts which are compensatable and are directly nested under the target activity, //and add them to our sorted list private static void CollectCompensatableCompletedContexts(ActivityExecutionContext context, Activity targetActivity, SortedDictionary <int, CompensationInfo> sortedListOfCompensatableTargets, bool immediateCompensation) { // walk through all completed execution contexts, add them to our sorted list ActivityExecutionContextManager contextManager = context.ExecutionContextManager; for (int index = contextManager.CompletedExecutionContexts.Count - 1; index >= 0; index--) { //if the context does not have any compensatable children, continue ActivityExecutionContextInfo completedActivityInfo = contextManager.CompletedExecutionContexts[index]; if ((completedActivityInfo.Flags & PersistFlags.NeedsCompensation) == 0) { continue; } //ok, found a compensatable child. Activity completedActivity = targetActivity.GetActivityByName(completedActivityInfo.ActivityQualifiedName, true); if (completedActivity != null && !(immediateCompensation && IsActivityInBackWorkBranch(targetActivity, completedActivity))) { sortedListOfCompensatableTargets.Add(completedActivityInfo.CompletedOrderId, new CompensationInfo(completedActivityInfo, contextManager)); } } }
internal ActivityExecutionContext(ActivityExecutionContextManager manager, Activity activity) { this.activity = activity; this.manager = manager; guid = Guid.NewGuid(); }
internal CompensationInfo(ActivityExecutionContextInfo targetExecutionInfo, ActivityExecutionContextManager targetExecutionContextManager) { this.targetExecutionInfo = targetExecutionInfo; this.targetExecutionContextManager = targetExecutionContextManager; }
public void Start () { WorkflowSchedulerService sheduler; // init all activities ActivityExecutionContextManager manager = new ActivityExecutionContextManager (this); ActivityExecutionContext context = manager.CreateExecutionContext (GetWorkflowDefinition ()); GetWorkflowDefinition ().InitializeInternal (context); sheduler = (WorkflowSchedulerService) runtime.GetService (typeof (WorkflowSchedulerService)); //sheduler.Schedule (new WaitCallback (WorkflowProcessor.RunWorkflow), guid); WorkflowProcessor.RunWorkflow (guid); }
// Workflow processor internal static void RunWorkflow (Object stateInfo) { Stack <Activity> stack = new Stack <Activity> (); WorkflowInstance wi = WorkflowRuntime.GetInstanceFromGuid ((Guid)stateInfo); wi.timer_subscriptions = new Timer (TimerSubscriptionsCallback, wi, 0, 1000); Activity activity = wi.GetWorkflowDefinition (); Activity next_activity; ActivityExecutionContextManager manager = new ActivityExecutionContextManager (wi); ActivityExecutionContext context; List <DelayActivity> waiting = new List <DelayActivity> (); bool wait = false; StateMachineWorkflowActivity state_machine = null; #if DEBUG_EXECUTIONLOOP Console.WriteLine ("Initiating thread for activity {0}", wi.GetWorkflowDefinition ()); #endif context = manager.CreateExecutionContext (activity); // Main Workflow execution loop while (activity != null) { next_activity = null; if (activity.NeedsExecution) { #if DEBUG_EXECUTIONLOOP Console.WriteLine ("*** Executing {0}, parallel {1}", activity, activity.ParallelParent); #endif context.ExecuteActivity (activity); } // If this a state machine changing its statge update StateMachineWorkflowActivity if (state_machine != null && IsBasedOnType (activity, typeof (SetStateActivity))) { state_machine.SetCurrentStateName (((SetStateActivity) activity).TargetStateName); } #if DEBUG_EXECUTIONLOOP Console.WriteLine (" ActivitiesToExecute.Count {0}, stack {1}, waiting {2}", activity.ActivitiesToExecute.Count, stack.Count, waiting.Count); #endif wait = false; // State machine workflow, first activity is InitialStateName if (IsBasedOnType (activity, typeof (StateMachineWorkflowActivity))) { state_machine = (StateMachineWorkflowActivity) activity; stack.Push (activity.GetActivityByName (state_machine.InitialStateName)); state_machine.SetCurrentStateName (state_machine.InitialStateName); #if DEBUG_EXECUTIONLOOP Console.WriteLine (" StateMachineWorkflowActivity, pushing {0}", activity.GetActivityByName (sm.InitialStateName)); #endif } // TODO: if (IsBasedOnType (current, typeof (CompositeActivity))) { if (activity.GetType () == typeof (DelayActivity)) { if (activity.ParallelParent == null) { wi.WorkflowRuntime.OnWorkflowIdled (wi); waiting.Add ((DelayActivity) activity); wait = true; } else { // Continue from parent activities // TODO: This can be moved to the Execute method // of the paralell activity if (activity.ParallelParent.ActivitiesToExecute.Count > 0) { stack.Push (activity.ParallelParent); #if DEBUG_EXECUTIONLOOP Console.WriteLine ("Pushing parent {0}", activity.ParallelParent); #endif waiting.Add ((DelayActivity) activity); } else { // If not possible, wait for the delay #if DEBUG_EXECUTIONLOOP Console.WriteLine ("Schedule Waiting"); #endif waiting.Add ((DelayActivity) activity); wait = true; } } } if (activity.NeedsExecution) { // ex. While stack.Push (activity); } if (activity.ActivitiesToExecute.Count == 0 && stack.Count == 0 && waiting.Count == 0) { #if DEBUG_EXECUTIONLOOP Console.WriteLine ("Exiting..."); #endif break; } // Does it have sub-activities to run? // Delay is not composite, cannot have children activities if (wait == false) { if (activity.ActivitiesToExecute.Count > 0) { next_activity = activity.ActivitiesToExecute.Dequeue (); #if DEBUG_EXECUTIONLOOP Console.WriteLine ("Next Activity A {0}", next_activity); #endif if (activity.ActivitiesToExecute.Count > 0) { stack.Push (activity); } } else { if (stack.Count > 0) { next_activity = stack.Pop (); } if (next_activity != null && next_activity.NeedsExecution == false) { if (next_activity.ActivitiesToExecute.Count > 0) { next_activity = next_activity.ActivitiesToExecute.Dequeue (); } } #if DEBUG_EXECUTIONLOOP Console.WriteLine ("Next Activity B {0}", next_activity); #endif } } if (next_activity == null) { if (waiting.Count > 0) { #if DEBUG_EXECUTIONLOOP Console.WriteLine ("Waiting for {0} handles...", waiting.Count); #endif wi.WorkflowRuntime.OnWorkflowIdled (wi); DelayActivity.WaitEvent.WaitOne (); } } // Do we have delay activities no longer waiting? foreach (DelayActivity delay in waiting) { if (delay.Delayed == false) { bool flag = false; // Continue with the list of activities pending in the parent next_activity = delay.Parent; waiting.Remove (delay); #if DEBUG_EXECUTIONLOOP Console.WriteLine ("Delayed Parent {0}", next_activity); #endif if (next_activity.ActivitiesToExecute.Count > 0) { if (next_activity.ActivitiesToExecute.Count > 1) flag = true; if (next_activity != null) { next_activity = next_activity.ActivitiesToExecute.Dequeue (); if (flag == true) { stack.Push (delay.Parent); } } } break; } } #if DEBUG_EXECUTIONLOOP Console.WriteLine ("Next activity to process {0}", next_activity); #endif activity = next_activity; } wi.WorkflowRuntime.OnWorkflowCompleted (wi); }
private ActivityExecutionStatus CompensateTargetActivity(ActivityExecutionContext context) { Activity targetActivity = null; Activity commonParentActivity = context.Activity; do { commonParentActivity = commonParentActivity.Parent; targetActivity = commonParentActivity.GetActivityByName(this.TargetActivityName, true); } while (targetActivity == null); if (targetActivity is ICompensatableActivity && targetActivity.ExecutionStatus == ActivityExecutionStatus.Closed && targetActivity.ExecutionResult == ActivityExecutionResult.Succeeded) { // same execution context targetActivity.RegisterForStatusChange(Activity.ClosedEvent, this); context.CompensateActivity(targetActivity); return(context.Activity.ExecutionStatus); } else if (targetActivity.ExecutionStatus == ActivityExecutionStatus.Initialized) { // Template activity // walk through active contexts ActivityExecutionContextManager contextManager = context.ExecutionContextManager; foreach (ActivityExecutionContext activeContext in contextManager.ExecutionContexts) { if (targetActivity.GetActivityByName(activeContext.Activity.QualifiedName, true) != null) { if (activeContext.Activity.ExecutionStatus == ActivityExecutionStatus.Compensating || activeContext.Activity.ExecutionStatus == ActivityExecutionStatus.Faulting || activeContext.Activity.ExecutionStatus == ActivityExecutionStatus.Canceling ) { return(context.Activity.ExecutionStatus); } } } // walk through all completed execution contexts for (int index = contextManager.CompletedExecutionContexts.Count - 1; index >= 0; index--) { //only compensate direct child during explicit compensation ActivityExecutionContextInfo completedActivityInfo = contextManager.CompletedExecutionContexts[index]; if (((completedActivityInfo.Flags & PersistFlags.NeedsCompensation) != 0)) { ActivityExecutionContext revokedExecutionContext = contextManager.DiscardPersistedExecutionContext(completedActivityInfo); if (revokedExecutionContext.Activity is ICompensatableActivity) { revokedExecutionContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, this); revokedExecutionContext.CompensateActivity(revokedExecutionContext.Activity); } return(context.Activity.ExecutionStatus); } } } else { // currently faulting, canceling, or compensating if (CompensationUtils.TryCompensateLastCompletedChildActivity(context, targetActivity, this)) { return(context.Activity.ExecutionStatus); } } return(ActivityExecutionStatus.Closed); }