Ejemplo n.º 1
0
        public async Task EndSequence()
        {
            if (status == null)
            {
                throw new JobFacInvalidRunStatusException($"Sequence has not been started (instance {jobInstanceKey})");
            }

            currentStep = null;
            await StoreNewRunStatus(RunStatus.Ended);
        }
Ejemplo n.º 2
0
        private async Task StartNextStep(int skipToStepNumber = 0)
        {
            var stepNum = (skipToStepNumber == 0) ? ++status.JobTypeProperties.SequenceStep : skipToStepNumber;

            currentStep = steps.Where(s => s.Step == stepNum).FirstOrDefault();

            // TODO set correct status and wrap up job processing before throwing
            if (currentStep == null)
            {
                throw new JobFacInvalidDataException($"Step {stepNum} not defined for sequence {jobDefinition.Id}");
            }

            var stepStatus = new StatusSequenceStep {
                Step = status.JobTypeProperties.SequenceStep
            };

            status.JobTypeProperties.StepStatus.Add(stepNum, stepStatus);

            if (!await ProcessStartDecision())
            {
                return;
            }

            var jobIds = Formatting.SplitCommaSeparatedList(currentStep.JobDefinitionIdList);

            foreach (var id in jobIds)
            {
                var options = new FactoryStartOptions
                {
                    DefinitionId       = id,
                    SequenceInstanceId = jobInstanceKey,
                    // TODO filter spawned-job args/payloads to the specific job?
                    ReplacementArguments = status.StartOptions.ReplacementArguments,
                    StartupPayloads      = status.StartOptions.StartupPayloads
                };
                var jobId = await jobFactory.StartJob(options);

                status.JobTypeProperties.JobInstanceStepMap.Add(jobId, stepNum);
                stepStatus.JobStatus.Add(jobId, new JobStatus <StatusExternalProcess>
                {
                    Key          = jobId,
                    StartOptions = options,
                    RunStatus    = RunStatus.Unknown,
                });
            }

            await StoreNewRunStatus(RunStatus.Running);

            if (currentStep.ExitDecision == StepExitDecision.DoNextStepWithoutWaiting)
            {
                await StartNextStep();
            }

            // local function returns value indicating whether to continue start-up
            async Task <bool> ProcessStartDecision()
            {
                // The validator ensures StartDates and StartTimes are correct.
                if (currentStep.StartDateDecision != StepStartDateDecision.NoDecision)
                {
                    var analysis = DateTimeAnalysis.Now(currentStep.StartDecisionTimeZone);

                    var  dates         = Formatting.SplitCommaSeparatedList(currentStep.StartDates);
                    bool startDecision = currentStep.StartDateDecision switch
                    {
                        // see scheduler TargetPlanner for descriptions
                        StepStartDateDecision.DaysOfWeek => analysis.InDaysOfWeek(dates),
                        StepStartDateDecision.DaysOfMonth => analysis.InDaysOfMonth(dates),
                        StepStartDateDecision.SpecificDates => analysis.InSpecificDates(dates),
                        StepStartDateDecision.DateRanges => analysis.InDateRanges(dates),
                        StepStartDateDecision.Weekdays => analysis.InWeekdays(dates),
                        _ => true,
                    };

                    if (startDecision && currentStep.StartTimeDecision != StepStartTimeDecision.NoDecision)
                    {
                        var times = Formatting.SplitCommaSeparatedList(currentStep.StartTimes);
                        startDecision = currentStep.StartTimeDecision switch
                        {
                            StepStartTimeDecision.IfHours => analysis.InHours(times),
                            StepStartTimeDecision.IfMinutes => analysis.InMinutes(times),
                            StepStartTimeDecision.IfTime => analysis.InSpecificTimes(times),
                            StepStartTimeDecision.IfTimeRange => analysis.InTimeRanges(times),
                            _ => true,
                        };
                    }

                    stepStatus.StartDecisionSuccess = startDecision;

                    if (!startDecision)
                    {
                        await historyRepo.UpdateStatus(status);

                        switch (currentStep.StartFalseAction)
                        {
                        case StepAction.DoNextStep:
                            await StartNextStep();

                            break;

                        case StepAction.DoStepNumber:
                            await StartNextStep(currentStep.StartFalseStepNumber);

                            break;

                        case StepAction.EndSequence:
                            await Stop();

                            break;
                        }
                        return(false);
                    }
                }
                return(true);
            }
        }