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); }
private static bool TryCompensateLastCompletedChildActivity(ActivityExecutionContext context, Activity targetActivity, IActivityEventListener <ActivityExecutionStatusChangedEventArgs> statusChangeHandler, bool isimmediateCompensation) { SortedDictionary <int, CompensationInfo> sortedListOfCompensatableTargets = new SortedDictionary <int, CompensationInfo>(); if (targetActivity is CompositeActivity) { if (CollectCompensatableTargetActivities(targetActivity as CompositeActivity, sortedListOfCompensatableTargets, isimmediateCompensation)) { return(true); } if (CollectCompensatableActiveContexts(context, targetActivity, sortedListOfCompensatableTargets, isimmediateCompensation)) { return(true); } CollectCompensatableCompletedContexts(context, targetActivity, sortedListOfCompensatableTargets, isimmediateCompensation); if (sortedListOfCompensatableTargets.Count == 0) { CompleteRevokedExecutionContext(targetActivity, context); return(false); } int?nullable = targetActivity.GetValue(CompensationHandlingFilter.LastCompensatedOrderIdProperty) as int?; int num = -1; CompensationInfo info = null; foreach (int num2 in sortedListOfCompensatableTargets.Keys) { if (nullable.HasValue) { int?nullable2 = nullable; int num3 = num2; if ((nullable2.GetValueOrDefault() < num3) && nullable2.HasValue) { break; } } info = sortedListOfCompensatableTargets[num2]; num = num2; } if (info == null) { CompleteRevokedExecutionContext(targetActivity, context); return(false); } targetActivity.SetValue(CompensationHandlingFilter.LastCompensatedOrderIdProperty, num); if ((info.TargetActivity != null) && (info.TargetActivity is ICompensatableActivity)) { info.TargetActivity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler); context.CompensateActivity(info.TargetActivity); return(true); } if ((info.TargetExecutionInfo != null) && (info.TargetExecutionContextManager != null)) { ActivityExecutionContext context2 = info.TargetExecutionContextManager.DiscardPersistedExecutionContext(info.TargetExecutionInfo); if (context2.Activity is ICompensatableActivity) { context2.Activity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler); context2.CompensateActivity(context2.Activity); return(true); } if (context2.Activity is CompositeActivity) { Activity lastCompensatableChild = GetLastCompensatableChild(context2.Activity as CompositeActivity); if (lastCompensatableChild != null) { lastCompensatableChild.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler); context2.CompensateActivity(lastCompensatableChild); return(true); } return(TryCompensateLastCompletedChildActivity(context2, context2.Activity, statusChangeHandler, false)); } } else if ((info.TargetExecutionContext != null) && (info.TargetExecutionContext.Activity is CompositeActivity)) { Activity activity = GetLastCompensatableChild(info.TargetExecutionContext.Activity as CompositeActivity); if (activity != null) { activity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler); info.TargetExecutionContext.CompensateActivity(activity); return(true); } return(TryCompensateLastCompletedChildActivity(info.TargetExecutionContext, info.TargetExecutionContext.Activity, statusChangeHandler, false)); } } return(false); }
private static bool TryCompensateLastCompletedChildActivity(ActivityExecutionContext context, Activity targetActivity, IActivityEventListener <ActivityExecutionStatusChangedEventArgs> statusChangeHandler, bool isimmediateCompensation) { SortedDictionary <int, CompensationInfo> sortedListOfCompensatableTargets = new SortedDictionary <int, CompensationInfo>(); if (!(targetActivity is CompositeActivity)) { return(false); } //Walk through all of the direct children which are compensatable and add them in the sorted order of their completion //bail out if any of the compensatable children is currently compensating/faulting or canceling if (CollectCompensatableTargetActivities(targetActivity as CompositeActivity, sortedListOfCompensatableTargets, isimmediateCompensation)) { return(true); } // 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 if (CollectCompensatableActiveContexts(context, targetActivity, sortedListOfCompensatableTargets, isimmediateCompensation)) { return(true); } // walk through all completed execution contexts which are compensatable and are directly nested under the target activity, //and add them to our sorted list CollectCompensatableCompletedContexts(context, targetActivity, sortedListOfCompensatableTargets, isimmediateCompensation); //if there were no compensatable targets found, bail out if (sortedListOfCompensatableTargets.Count == 0) { CompleteRevokedExecutionContext(targetActivity, context); return(false); } int?lastCompletedOrderId = targetActivity.GetValue(CompensationHandlingFilter.LastCompensatedOrderIdProperty) as Nullable <int>; int nextLastCompletedOrderId = -1; //get the last compensatable target - this could be an activity, contextInfo or a Context CompensationInfo lastCompensatableTarget = null; foreach (int completedOrderId in sortedListOfCompensatableTargets.Keys) { if (lastCompletedOrderId.HasValue && lastCompletedOrderId < completedOrderId) { break; } lastCompensatableTarget = sortedListOfCompensatableTargets[completedOrderId]; nextLastCompletedOrderId = completedOrderId; } //We are done with compensation on entire branch, now complete execution contexts //recursilvely which we might have opened up. if (lastCompensatableTarget == null) { CompleteRevokedExecutionContext(targetActivity, context); return(false); } targetActivity.SetValue(CompensationHandlingFilter.LastCompensatedOrderIdProperty, nextLastCompletedOrderId); //the last compensatable target could be an activity if (lastCompensatableTarget.TargetActivity != null && lastCompensatableTarget.TargetActivity is ICompensatableActivity) { lastCompensatableTarget.TargetActivity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler); context.CompensateActivity(lastCompensatableTarget.TargetActivity); return(true); } //or get the last compensatable "completed" context else if (lastCompensatableTarget.TargetExecutionInfo != null && lastCompensatableTarget.TargetExecutionContextManager != null) { ActivityExecutionContext revokedExecutionContext = lastCompensatableTarget.TargetExecutionContextManager.DiscardPersistedExecutionContext(lastCompensatableTarget.TargetExecutionInfo); //get the "first" compensatable child and compensate it if (revokedExecutionContext.Activity is ICompensatableActivity) { revokedExecutionContext.Activity.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler); revokedExecutionContext.CompensateActivity(revokedExecutionContext.Activity); return(true); } else if (revokedExecutionContext.Activity is CompositeActivity) { //get the last compensatable child of the revoked context Activity compensatableChild = GetLastCompensatableChild(revokedExecutionContext.Activity as CompositeActivity); if (compensatableChild != null) { compensatableChild.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler); revokedExecutionContext.CompensateActivity(compensatableChild); return(true); } else// recursively, walk the context tree and keep revoking the compensatable contexts { return(TryCompensateLastCompletedChildActivity(revokedExecutionContext, revokedExecutionContext.Activity, statusChangeHandler, false)); } } } else if (lastCompensatableTarget.TargetExecutionContext != null) //or get the last compensatable "active" context { if (lastCompensatableTarget.TargetExecutionContext.Activity is CompositeActivity) { //get the last compensatable child of the active context Activity compensatableChild = GetLastCompensatableChild(lastCompensatableTarget.TargetExecutionContext.Activity as CompositeActivity); if (compensatableChild != null) { compensatableChild.RegisterForStatusChange(Activity.StatusChangedEvent, statusChangeHandler); lastCompensatableTarget.TargetExecutionContext.CompensateActivity(compensatableChild); return(true); } else // recursively, walk the context tree and keep revoking the compensatable contexts { return(TryCompensateLastCompletedChildActivity(lastCompensatableTarget.TargetExecutionContext, lastCompensatableTarget.TargetExecutionContext.Activity, statusChangeHandler, false)); } } } return(false); }
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); }