예제 #1
0
 void IDisposable.Dispose()
 {
     if (this.currentActivity != null)
     {
         if (this.contextManager != null)
         {
             this.contextManager.Dispose();
             this.contextManager = null;
         }
         this.currentActivity = null;
     }
 }
예제 #2
0
        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));
                    }
                }
            }
        }
예제 #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);
        }
        // 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));
                }
            }
        }
예제 #6
0
 internal ActivityExecutionContext(ActivityExecutionContextManager manager, Activity activity)
 {
     this.activity = activity;
     this.manager  = manager;
     guid          = Guid.NewGuid();
 }
예제 #7
0
 internal CompensationInfo(ActivityExecutionContextInfo targetExecutionInfo, ActivityExecutionContextManager targetExecutionContextManager)
 {
     this.targetExecutionInfo           = targetExecutionInfo;
     this.targetExecutionContextManager = targetExecutionContextManager;
 }
 internal CompensationInfo(ActivityExecutionContextInfo targetExecutionInfo, ActivityExecutionContextManager targetExecutionContextManager)
 {
     this.targetExecutionInfo = targetExecutionInfo;
     this.targetExecutionContextManager = targetExecutionContextManager;
 }
예제 #9
0
		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);
		}
예제 #10
0
		// 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);
        }