private void EndTask(Task task) { _logger.Debug($"Task ended. Status: {task.Status}", nameof(EndTask), task.Exception?.InnerException); JobRunStatus status; Exception exception = null; switch (task.Status) { case TaskStatus.RanToCompletion: status = JobRunStatus.Completed; break; case TaskStatus.Canceled: status = JobRunStatus.Canceled; break; case TaskStatus.Faulted: status = JobRunStatus.Faulted; exception = ExtractTaskException(task.Exception); break; default: status = JobRunStatus.Unknown; // actually, very strange and should never happen. break; } var now = TimeProvider.GetCurrentTime(); _runInfoBuilder.EndTime = now; _runInfoBuilder.Status = status; _runInfoBuilder.Exception = exception; var jobRunInfo = _runInfoBuilder.Build(); _initiator.JobRunsHolder.Finish(jobRunInfo); _tokenSource.Dispose(); _systemWriter.Dispose(); _initiator.OnTaskEnded(); }
protected override Task <TimeSpan> DoWork(CancellationToken token) { _logger.Debug("Entered method", nameof(DoWork)); var now = TimeProvider.GetCurrentTime(); var employeesToWakeUp = new List <Tuple <Employee, DueTimeInfo> >(); var earliest = JobExtensions.Never; lock (_lock) { _startedWorking = true; foreach (var employee in _employees.Values) { var info = employee.GetDueTimeInfoForVice(false); if (!info.HasValue) { continue; } var dueTime = info.Value.GetEffectiveDueTime(); if (now >= dueTime) { // due time has come! employeesToWakeUp.Add(Tuple.Create(employee, info.Value)); } else { earliest = DateTimeOffsetExtensions.Min(earliest, dueTime); } } } foreach (var tuple in employeesToWakeUp) { var employee = tuple.Item1; var isOverridden = tuple.Item2.IsDueTimeOverridden(); var reason = isOverridden ? JobStartReason.OverriddenDueTime : JobStartReason.ScheduleDueTime; var startResult = employee.Start(reason, token); switch (startResult) { case JobStartResult.Started: _logger.Information( $"Job '{employee.Name}' was started. Reason: '{reason}'.", nameof(DoWork)); break; case JobStartResult.CompletedSynchronously: _logger.Information( $"Job '{employee.Name}' completed synchronously. Reason of start was '{reason}'.", nameof(DoWork)); break; case JobStartResult.AlreadyRunning: _logger.Information( $"Job '{employee.Name}' already running. Attempted to start due to reason '{reason}'.", nameof(DoWork)); break; case JobStartResult.Disabled: _logger.Information( $"Job '{employee.Name}' is disabled. Attempted to start due to reason '{reason}'.", nameof(DoWork)); break; } // when to visit you again, Employee? var nextDueTimeInfo = employee.GetDueTimeInfoForVice(true); if (nextDueTimeInfo.HasValue ) // actually, should have, he could not finish work and got disposed that fast, but who knows... { var nextDueTime = nextDueTimeInfo.Value.GetEffectiveDueTime(); if (nextDueTime > now) { earliest = DateTimeOffsetExtensions.Min(earliest, nextDueTime); } } } var vacationTimeout = earliest - now; _logger.Debug($"Going to vacation, length is '{vacationTimeout}'.", nameof(DoWork)); return(Task.FromResult(vacationTimeout)); }