internal static Activity GetLastCompensatableChild(CompositeActivity compositeActivity)
        {
            Activity[] activities = CompensationUtils.GetCompensatableChildren(compositeActivity);
            if (activities != null && activities.Length > 0 && activities[activities.Length - 1] != null)
            {
                return(activities[activities.Length - 1]);
            }

            return(null);
        }
        void IActivityEventListener <ActivityExecutionStatusChangedEventArgs> .OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            ActivityExecutionContext context = sender as ActivityExecutionContext;

            if (context == null)
            {
                throw new ArgumentException("sender");
            }
            if (e.Activity == context.Activity)
            {
                if (context.Activity.HasPrimaryClosed && !((bool)context.Activity.GetValue(CompensateProcessedProperty)))
                {
                    context.Activity.SetValue(CompensateProcessedProperty, true);
                    if (context.Activity.ExecutionResult != ActivityExecutionResult.Compensated)
                    {
                        context.Activity.ReleaseLockOnStatusChange(this);
                    }
                    else
                    {
                        Activity compensationHandler = GetCompensationHandler(context.Activity);
                        if (compensationHandler != null)
                        {
                            compensationHandler.RegisterForStatusChange(Activity.ClosedEvent, this);
                            context.ExecuteActivity(compensationHandler);
                        }
                        else if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                        {
                            context.Activity.ReleaseLockOnStatusChange(this);
                        }
                    }
                }
            }
            else if ((e.Activity is CompensationHandlerActivity) && (e.ExecutionStatus == ActivityExecutionStatus.Closed))
            {
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
                context.Activity.ReleaseLockOnStatusChange(this);
            }
            else if (e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
                if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    context.Activity.ReleaseLockOnStatusChange(this);
                }
            }
        }
示例#3
0
        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);
        }
        void IActivityEventListener <ActivityExecutionStatusChangedEventArgs> .OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            ActivityExecutionContext context = sender as ActivityExecutionContext;

            if (context == null)
            {
                throw new ArgumentException("sender");
            }

            if (e.Activity == context.Activity)
            {
                if (context.Activity.HasPrimaryClosed && !(bool)context.Activity.GetValue(CompensateProcessedProperty))
                {
                    context.Activity.SetValue(CompensateProcessedProperty, true);
                    if (context.Activity.ExecutionResult == ActivityExecutionResult.Compensated)
                    {
                        // run compensation handler or do default compensation handling
                        Activity compensationHandler = GetCompensationHandler(context.Activity);
                        if (compensationHandler != null)
                        {
                            // subscribe for status change on compensation handler
                            compensationHandler.RegisterForStatusChange(Activity.ClosedEvent, this);

                            // execute compensation handler
                            context.ExecuteActivity(compensationHandler);
                        }
                        else
                        {
                            // do default compensation
                            if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                            {
                                // let activity get into closed state
                                context.Activity.ReleaseLockOnStatusChange(this);
                            }
                        }
                    }
                    else
                    {
                        // let activity get into closed state
                        context.Activity.ReleaseLockOnStatusChange(this);
                    }
                }
            }
            else if (e.Activity is CompensationHandlerActivity && e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                // remove subscriber for status change on compensation handler
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);

                // release lock on the primary activity
                context.Activity.ReleaseLockOnStatusChange(this);
            }
            else if (e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                // remove subscriber for status change on compensated activity
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);

                if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    // release lock on the primary activity
                    context.Activity.ReleaseLockOnStatusChange(this);
                }
            }
        }
示例#5
0
        public void OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            ActivityExecutionContext context = sender as ActivityExecutionContext;

            if (context == null)
            {
                throw new ArgumentException("sender");
            }

            // waiting for primary activity to close
            if (e.Activity == context.Activity)
            {
                if (context.Activity.HasPrimaryClosed &&
                    !(bool)context.Activity.GetValue(FaultAndCancellationHandlingFilter.FaultProcessedProperty))
                {
                    context.Activity.SetValue(FaultAndCancellationHandlingFilter.FaultProcessedProperty, true);

                    if (context.Activity.WasExecuting &&
                        context.Activity.ExecutionResult == ActivityExecutionResult.Faulted &&
                        context.Activity.GetValue(ActivityExecutionContext.CurrentExceptionProperty) != null)
                    {
                        // execute exceptionHandlers, iff activity has transitioned from Executing to Faulting.
                        CompositeActivity exceptionHandlersActivity = FaultAndCancellationHandlingFilter.GetFaultHandlers(context.Activity);
                        if (exceptionHandlersActivity != null)
                        {
                            // listen for FaultHandler status change events
                            exceptionHandlersActivity.RegisterForStatusChange(Activity.ClosedEvent, this);

                            // execute exception handlers
                            context.ExecuteActivity(exceptionHandlersActivity);
                        }
                        else
                        {
                            // compensate completed children
                            if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                            {
                                SafeReleaseLockOnStatusChange(context); // no children to compensate...release lock on to the close status of the activity
                            }
                        }
                    }
                    else if (context.Activity.ExecutionResult == ActivityExecutionResult.Canceled)
                    {
                        // if primary activity is closed and outcome is canceled, then run the cancel handler
                        Activity cancelHandler = FaultAndCancellationHandlingFilter.GetCancellationHandler(context.Activity);
                        if (cancelHandler != null)
                        {
                            // execute the cancel handler
                            cancelHandler.RegisterForStatusChange(Activity.ClosedEvent, this);
                            context.ExecuteActivity(cancelHandler);
                        }
                        else
                        {
                            // run default compensation
                            if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                            {
                                SafeReleaseLockOnStatusChange(context); // release lock on to the close status of the activity
                            }
                        }
                    }
                    else // release lock on to the close status of the activity
                    {
                        SafeReleaseLockOnStatusChange(context);
                    }
                }
            }
            else if ((e.Activity is FaultHandlersActivity || e.Activity is CancellationHandlerActivity)
                     &&
                     (e.ExecutionStatus == ActivityExecutionStatus.Closed)
                     )
            {
                // remove subscriber
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);

                // fetch the exception , it would be null if it was handled
                if (context.Activity.GetValue(ActivityExecutionContext.CurrentExceptionProperty) != null)
                {
                    // the exception was not handled by exceptionHandlers.... do default exceptionHandling
                    // compesate completed children
                    if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                    {
                        SafeReleaseLockOnStatusChange(context); // no children to compensate.Release lock on to the close status of the activity
                    }
                }
                else// the exception was handled by the exceptionHandlers. Release lock on to the close status of the parent activity
                {
                    SafeReleaseLockOnStatusChange(context);
                }
            }
            else if (e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                // compensation of a child was in progress. // remove subscriber for this
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);

                // see if there are other children to be compensated
                if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    SafeReleaseLockOnStatusChange(context); // release lock on to the close status of the parent activity
                }
            }
        }
        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);
        }
示例#7
0
        public void OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            ActivityExecutionContext context = sender as ActivityExecutionContext;

            if (context == null)
            {
                throw new ArgumentException("sender");
            }
            if (e.Activity == context.Activity)
            {
                if (context.Activity.HasPrimaryClosed && !((bool)context.Activity.GetValue(FaultProcessedProperty)))
                {
                    context.Activity.SetValue(FaultProcessedProperty, true);
                    if ((!context.Activity.WasExecuting || (context.Activity.ExecutionResult != ActivityExecutionResult.Faulted)) || (context.Activity.GetValue(ActivityExecutionContext.CurrentExceptionProperty) == null))
                    {
                        if (context.Activity.ExecutionResult != ActivityExecutionResult.Canceled)
                        {
                            this.SafeReleaseLockOnStatusChange(context);
                        }
                        else
                        {
                            Activity cancellationHandler = GetCancellationHandler(context.Activity);
                            if (cancellationHandler != null)
                            {
                                cancellationHandler.RegisterForStatusChange(Activity.ClosedEvent, this);
                                context.ExecuteActivity(cancellationHandler);
                            }
                            else if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                            {
                                this.SafeReleaseLockOnStatusChange(context);
                            }
                        }
                    }
                    else
                    {
                        CompositeActivity faultHandlers = GetFaultHandlers(context.Activity);
                        if (faultHandlers != null)
                        {
                            faultHandlers.RegisterForStatusChange(Activity.ClosedEvent, this);
                            context.ExecuteActivity(faultHandlers);
                        }
                        else if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                        {
                            this.SafeReleaseLockOnStatusChange(context);
                        }
                    }
                }
            }
            else if (((e.Activity is FaultHandlersActivity) || (e.Activity is CancellationHandlerActivity)) && (e.ExecutionStatus == ActivityExecutionStatus.Closed))
            {
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
                if (context.Activity.GetValue(ActivityExecutionContext.CurrentExceptionProperty) == null)
                {
                    this.SafeReleaseLockOnStatusChange(context);
                }
                else if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    this.SafeReleaseLockOnStatusChange(context);
                }
            }
            else if (e.ExecutionStatus == ActivityExecutionStatus.Closed)
            {
                e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, this);
                if (!CompensationUtils.TryCompensateLastCompletedChildActivity(context, context.Activity, this))
                {
                    this.SafeReleaseLockOnStatusChange(context);
                }
            }
        }