示例#1
0
        /// <summary>
        ///
        /// </summary>
        StepInfo GetStepFromHistory(WorkflowStepElement stepConfig)
        {
            foreach (StepInfo s in _stepHistory)
            {
                // Check whether the next step hasn't been added already
                if (s.StepConfig == stepConfig)
                {
                    return(s);
                }
            }

            return(null);
        }
示例#2
0
        void OnChildServiceRequested(int stepNumber, int attemptNumber, SettingsCollection options)
        {
            // Get the step configuration elements
            WorkflowStepElement           stepConfig   = this.Configuration.Workflow[stepNumber];
            AccountServiceSettingsElement stepSettings =
                this.Configuration.StepSettings != null ?
                this.Configuration.StepSettings[stepConfig] :
                null;

            // Take the step configuration
            ActiveServiceElement configuration = stepSettings != null ?
                                                 new ActiveServiceElement(stepSettings) :
                                                 new ActiveServiceElement(stepConfig);

            // Add child-specific options
            if (options != null)
            {
                configuration.Options.Merge(options);
            }

            // Add parent options, without overriding child options with the same name
            foreach (var parentOption in this.Configuration.Options)
            {
                if (!configuration.Options.ContainsKey(parentOption.Key))
                {
                    configuration.Options.Add(parentOption.Key, parentOption.Value);
                }
            }

            // Add parent extensions, without overriding child options with the same name
            foreach (var parentExtension in this.Configuration.Extensions)
            {
                if (!configuration.Extensions.ContainsKey(parentExtension.Key))
                {
                    configuration.Extensions.Add(parentExtension.Key, parentExtension.Value);
                }
            }

            // Generate a child instance
            ServiceInstance child = Service.CreateInstance(configuration, this, this.AccountID);

            child.StateChanged     += _childStateHandler;
            child.OutcomeReported  += _childOutcomeHandler;
            child.ProgressReported += _childProgressHandler;
            _childServices.Add(child, stepNumber);

            if (ChildServiceRequested != null)
            {
                ChildServiceRequested(this, new ServiceRequestedEventArgs(child, attemptNumber));
            }
        }
示例#3
0
        public AccountServiceSettingsElement this[WorkflowStepElement step]
        {
            get
            {
                foreach (AccountServiceSettingsElement elem in this)
                {
                    if (elem.Step.Element == step)
                    {
                        return(elem);
                    }
                }

                return(null);
            }
        }
示例#4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="nextStepConfig"></param>
        /// <returns></returns>
        bool IsInStepHistory(WorkflowStepElement nextStepConfig)
        {
            bool alreadyAdded = false;

            foreach (StepInfo s in _stepHistory)
            {
                // Check whether the next step hasn't been added already
                if (s.StepConfig == nextStepConfig)
                {
                    alreadyAdded = true;
                    break;
                }
            }

            return(alreadyAdded);
        }
示例#5
0
        /// <summary>
        /// Gets the next step that is enabled and is not a failure handler. If there is none returns null.
        /// </summary>
        WorkflowStepElement GetNextStep(WorkflowStepElement stepConfig)
        {
            int indexOfCurrent = stepConfig == null ? 0 : Instance.Configuration.Workflow.IndexOf(stepConfig) + 1;

            // Find the next non-failure handler step
            WorkflowStepElement next = null;

            for (int i = indexOfCurrent; i < Instance.Configuration.Workflow.Count; i++)
            {
                WorkflowStepElement step = Instance.Configuration.Workflow[i];
                if (
                    step.IsEnabled &&
                    !step.IsFailureHandler                     // &&
                    //IsStepConditionValid(step.ConditionOptions, step.Condition)
                    )
                {
                    next = Instance.Configuration.Workflow[i];
                    break;
                }
            }

            return(next);
        }
示例#6
0
 public ServiceDisplayInfo(ServiceElement configuration, WorkflowStepElement step) : this(configuration, step.Name)
 {
     _step = step;
 }
示例#7
0
        /// <summary>
        ///
        /// </summary>
        protected virtual ServiceOutcome DoWork()
        {
            if (Outcome != ServiceOutcome.Unspecified || State != ServiceState.Running)
            {
                throw new InvalidOperationException("DoWork() cannot be called because the service has ended.");
            }

            // Simulate processing execution time
            if (Instance.Configuration.DebugDelay != TimeSpan.Zero)
            {
                Thread.Sleep(Instance.Configuration.DebugDelay);
            }

            // Service with no steps means instant success!
            if (Instance.Configuration.Workflow.Count < 1)
            {
                return(ServiceOutcome.Success);
            }

            // Add the first step of the history as null - indicator for starting
            if (_stepHistory.Count < 1)
            {
                _stepHistory.Add(null);
            }

            // The return result
            bool stepsInProgress = false;

            ServiceOutcome outcome = ServiceOutcome.Unspecified;

            // Loop over each step in the history
            foreach (StepInfo step in _stepHistory.ToArray())
            {
                bool moveToNextStep = true;

                if (step != null)
                {
                    stepsInProgress = stepsInProgress || step.ServiceState != ServiceState.Ended;

                    // As long as a blocking process is running, halt all processing
                    if (stepsInProgress && step.Config.IsBlocking)
                    {
                        break;
                    }

                    // Indicates whether to process next step
                    moveToNextStep = step.ServiceOutcome == ServiceOutcome.Success;

                    if (!step.FailureWasHandled && (step.ServiceOutcome == ServiceOutcome.Failure || step.ServiceOutcome == ServiceOutcome.Aborted))
                    {
                        if (step.FailureRepetitions < step.Config.FailureRepeat - 1 && step.ServiceOutcome != ServiceOutcome.Aborted)
                        {
                            step.ServiceState = ServiceState.Uninitialized;
                            step.FailureRepetitions++;
                        }
                        else
                        {
                            if (step.Config.FailureOutcome == FailureOutcome.Continue)
                            {
                                // Process same as Success
                                moveToNextStep = true;
                            }

                            // This here is due to base[] getter bug
                            else if
                            (
                                !step.Config.IsFailureHandler &&
                                step.Config.FailureHandler.Element != null &&
                                step.Config.FailureHandler.Element.BaseConfiguration.Element.Name != null &&
                                !IsInStepHistory(step.Config.FailureHandler.Element)                                 //&&
                                //IsStepConditionValid(step.Config.FailureHandler.Element.ConditionOptions, step.Config.FailureHandler.Element.Condition)
                            )
                            {
                                // Get the correct step element
                                AccountServiceSettingsElement stepSettings = Instance.Configuration.StepSettings != null ? Instance.Configuration.StepSettings[step.Config.FailureHandler.Element] : null;

                                // Add a new step, the failure handler
                                if (stepSettings != null)
                                {
                                    _stepHistory.Add(new StepInfo(stepSettings));
                                }
                                else
                                {
                                    _stepHistory.Add(new StepInfo(step.Config.FailureHandler.Element));
                                }

                                // Done handling this step's failure
                                step.FailureWasHandled = true;
                            }
                            else
                            {
                                // Terminate because there is no failure handling - abort and stop processing
                                outcome = ServiceOutcome.Failure;
                                break;
                            }
                        }
                    }
                }

                if (moveToNextStep)
                {
                    // Get rid of the first null used to jump start the processing loop
                    if (step == null)
                    {
                        _stepHistory.Remove(step);
                    }

                    // Get the next step of a failure handler
                    WorkflowStepElement nextStepConfig = GetNextStep(step == null ? null : step.StepConfig);

                    if (nextStepConfig == null)
                    {
                        // No steps left to process
                        if (_stepHistory.TrueForAll(new Predicate <StepInfo>(delegate(StepInfo s) { return(s.ServiceState == ServiceState.Ended); })))
                        {
                            // All steps ended - outcome successful
                            outcome = ServiceOutcome.Success;
                            break;
                        }
                        else
                        {
                            // There are still steps being run so wait for them to complete before reporting that we are done
                            continue;
                        }
                    }
                    else if (nextStepConfig.WaitForPrevious && stepsInProgress)
                    {
                        // The next step needs to wait for all previous steps to end - stop processing
                        break;
                    }
                    else
                    {
                        bool adding = true;
                        while (adding)
                        {
                            if (!IsInStepHistory(nextStepConfig))
                            {
                                // Get the correct step element
                                AccountServiceSettingsElement stepSettings = Instance.Configuration.StepSettings != null ? Instance.Configuration.StepSettings[nextStepConfig] : null;

                                // Schedule the next step as long as it hasn't been added already
                                if (stepSettings != null)
                                {
                                    _stepHistory.Add(new StepInfo(stepSettings));
                                }
                                else
                                {
                                    _stepHistory.Add(new StepInfo(nextStepConfig));
                                }
                            }

                            // If the step is blocking or if it's a failure handler, stop adding steps, otherwise add the next
                            if (nextStepConfig.IsBlocking || nextStepConfig == Instance.Configuration.Workflow[Instance.Configuration.Workflow.Count - 1])
                            {
                                adding = false;
                            }
                            else
                            {
                                nextStepConfig = GetNextStep(nextStepConfig);

                                // Only add the next if it doesn't require previous steps to end first
                                if (nextStepConfig == null || nextStepConfig.WaitForPrevious)
                                {
                                    adding = false;
                                }
                            }
                        }
                    }
                }
            }

            if (outcome == ServiceOutcome.Unspecified)
            {
                // Request any pending child steps to be run
                foreach (StepInfo step in _stepHistory)
                {
                    if (step.ServiceState == ServiceState.Uninitialized)
                    {
                        RequestChildService(Instance.Configuration.Workflow.IndexOf(step.StepConfig), step.FailureRepetitions + 1);
                    }
                }
            }

            return(outcome);
        }
示例#8
0
 /// <summary>
 ///
 /// </summary>
 public StepInfo(WorkflowStepElement stepConfig)
 {
     StepConfig = stepConfig;
     Config     = new ActiveWorkflowStepElement(StepConfig);
 }
示例#9
0
        /*=========================*/
        #endregion

        #region Constructors
        /*=========================*/

        /// <summary>
        ///
        /// </summary>
        public StepInfo(AccountServiceSettingsElement accountStepConfig)
        {
            StepConfig        = accountStepConfig.Step.Element;
            AccountStepConfig = accountStepConfig;
            Config            = new ActiveWorkflowStepElement(AccountStepConfig);
        }