private RunContext Run(JobStartReason startReason, CancellationToken?token) { // always guarded by '_lock' var runContext = new RunContext(this, startReason, token); var startedRunContext = runContext.Start(); return(startedRunContext); }
internal JobRunInfoBuilder( int runIndex, JobStartReason startReason, DateTimeOffset dueTime, bool dueTimeWasOverridden, DateTimeOffset startTime, JobRunStatus status, StringWriter outputWriter) { this.RunIndex = runIndex; this.StartReason = startReason; this.DueTime = dueTime; this.DueTimeWasOverridden = dueTimeWasOverridden; this.StartTime = startTime; this.Status = status; this.OutputWriter = outputWriter; }
public JobRunInfo( int runIndex, JobStartReason startReason, DateTimeOffset dueTime, bool dueTimeWasOverridden, DateTimeOffset startTime, DateTimeOffset?endTime, JobRunStatus status, string output, Exception exception) { // todo checks: positive etc // todo date is valid this.RunIndex = runIndex; this.StartReason = startReason; this.DueTime = dueTime; this.DueTimeWasOverridden = dueTimeWasOverridden; this.StartTime = startTime; this.EndTime = endTime; this.Status = status; this.Output = output; this.Exception = exception; }
internal RunContext( Runner initiator, JobStartReason startReason, CancellationToken?token) { _initiator = initiator; var jobProperties = _initiator.JobPropertiesHolder.ToJobProperties(); _tokenSource = token.HasValue ? CancellationTokenSource.CreateLinkedTokenSource(token.Value) : new CancellationTokenSource(); _systemWriter = new StringWriterWithEncoding(Encoding.UTF8); var writers = new List <TextWriter> { _systemWriter, }; if (jobProperties.Output != null) { writers.Add(jobProperties.Output); } var multiTextWriter = new MultiTextWriter(Encoding.UTF8, writers); var dueTimeInfo = _initiator.DueTimeHolder.GetDueTimeInfo(); var dueTime = dueTimeInfo.GetEffectiveDueTime(); var dueTimeWasOverridden = dueTimeInfo.IsDueTimeOverridden(); var now = TimeProvider.GetCurrentTime(); _runInfoBuilder = new JobRunInfoBuilder( initiator.JobRunsHolder.Count, startReason, dueTime, dueTimeWasOverridden, now, JobRunStatus.Running, _systemWriter); _logger = new ObjectLogger(this, _initiator.JobName) { IsEnabled = _initiator.IsLoggingEnabled, }; try { _task = jobProperties.Routine( jobProperties.Parameter, jobProperties.ProgressTracker, multiTextWriter, _tokenSource.Token); // todo: if routine returns null? if (_task.IsFaulted && _task.Exception != null) { var ex = ExtractTaskException(_task.Exception); multiTextWriter.WriteLine(ex); _logger.Warning("Routine has thrown an exception.", "ctor", ex); _task = Task.FromException(ex); } } catch (Exception ex) { // it is not an error if Routine throws, but let's log it as a warning. multiTextWriter.WriteLine(ex); _logger.Warning("Routine has thrown an exception.", "ctor", ex); _task = Task.FromException(ex); } }
internal JobStartResult Start(JobStartReason startReason, CancellationToken?token) { if (startReason == JobStartReason.Force) { lock (_lock) { this.CheckNotDisposed(); if (this.IsRunning) { throw new JobException($"Job '{this.JobName}' is already running."); } if (!this.IsEnabled) { throw new JobException($"Job '{this.JobName}' is disabled."); } _runContext = this.Run(startReason, token); if (_runContext == null) { return(JobStartResult.CompletedSynchronously); } return(JobStartResult.Started); } } else { lock (_lock) { try { if (this.IsRunning) { return(JobStartResult.AlreadyRunning); } if (!this.IsEnabled) { return(JobStartResult.Disabled); } _runContext = this.Run(startReason, token); if (_runContext == null) { return(JobStartResult.CompletedSynchronously); } return(JobStartResult.Started); } finally { // started via due time (either overridden or scheduled), so clear overridden due time. this.DueTimeHolder.OverriddenDueTime = null; } } } }