private async Task <Job> CreateNewJobAsync(CancellationToken cancellationToken = default) { var schedulerSetting = await _jobStore.GetSchedulerMetadataAsync(cancellationToken); // If there are failedJobs, continue the progress from a new job. if (schedulerSetting?.FailedJobs?.Any() == true) { var failedJob = schedulerSetting.FailedJobs.First(); var resumeJob = Job.Create( failedJob.ContainerName, JobStatus.New, failedJob.DataPeriod, failedJob.FilterInfo, failedJob.Patients, failedJob.NextTaskIndex, failedJob.RunningTasks, failedJob.TotalResourceCounts, failedJob.ProcessedResourceCounts, failedJob.SkippedResourceCounts, failedJob.PatientVersionId, failedJob.Id); // update the job id of running task, which is used to generate the result blob file name foreach (var runningTask in resumeJob.RunningTasks.Values) { runningTask.JobId = resumeJob.Id; } return(resumeJob); } DateTimeOffset triggerStart = GetTriggerStartTime(schedulerSetting); if (triggerStart >= _jobConfiguration.EndTime) { _logger.LogInformation($"The job trigger start time {triggerStart} is greater than the end time {_jobConfiguration.EndTime} in configuration, no need to start a new job."); return(null); } // End data period for this trigger DateTimeOffset triggerEnd = GetTriggerEndTime(); if (triggerStart >= triggerEnd) { _logger.LogError("The start time '{triggerStart}' to trigger is in the future.", triggerStart); throw new StartJobFailedException($"The start time '{triggerStart}' to trigger is in the future."); } var typeFilters = _typeFilterParser.CreateTypeFilters( _filterConfiguration.FilterScope, _filterConfiguration.RequiredTypes, _filterConfiguration.TypeFilters); var processedPatients = schedulerSetting?.ProcessedPatients; var filterInfo = new FilterInfo(_filterConfiguration.FilterScope, _filterConfiguration.GroupId, _jobConfiguration.StartTime, typeFilters, processedPatients); var newJob = Job.Create( _jobConfiguration.ContainerName, JobStatus.New, new DataPeriod(triggerStart, triggerEnd), filterInfo); return(newJob); }