void OnChildServiceRequested(int stepNumber, int attemptNumber)
        {
            // Get the step configuration elements
            ExecutionStepElement          stepConfig   = this.Configuration.ExecutionSteps[stepNumber];
            AccountServiceSettingsElement stepSettings =
                this.Configuration.StepSettings != null ?
                this.Configuration.StepSettings[stepConfig] :
                null;

            // Generate a child instance
            ServiceInstance child = Service.CreateInstance(
                stepSettings != null ?
                (EnabledConfigurationElement)stepSettings :
                (EnabledConfigurationElement)stepConfig,
                this,
                this.AccountID);

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

            if (ChildServiceRequested != null)
            {
                ChildServiceRequested(this, new ServiceRequestedEventArgs(child, attemptNumber));
            }
        }
Beispiel #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));
            }
        }
Beispiel #3
0
        /*=========================*/
        #endregion

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

        /// <summary>
        ///
        /// </summary>
        public StepInfo(AccountServiceSettingsElement accountStepConfig)
        {
            StepConfig        = accountStepConfig.Step.Element;
            AccountStepConfig = accountStepConfig;
            Config            = new ActiveExecutionStepElement(AccountStepConfig);
        }
Beispiel #4
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 > 0)
            {
                Thread.Sleep(Instance.Configuration.DebugDelay);
            }

            // Service with no steps means instant success!
            if (Instance.Configuration.ExecutionSteps.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.CouldNotBeScheduled || 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.ServiceToUse.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
                    ExecutionStepElement 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.ExecutionSteps[Instance.Configuration.ExecutionSteps.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.ExecutionSteps.IndexOf(step.StepConfig), step.FailureRepetitions + 1);
                    }
                }
            }

            return(outcome);
        }