/// <summary> /// Write an exception to the console output. /// </summary> public static void WriteException( this PerformContext console, Exception exception) => console.WriteLine($"{exception.Message}\n{exception.StackTrace}");
internal PerformContext([NotNull] PerformContext context) : this(context.Connection, context.BackgroundJob, context.CancellationToken) { Items = context.Items; }
/// <summary> /// Write an empty line to the console output. /// </summary> public static void Flush( this PerformContext console) => console.WriteLine();
public PerformContext([NotNull] PerformContext context) : this(context.Connection, context.BackgroundJob, context.CancellationToken, context.Profiler, context._scope) { Items = context.Items; }
private void ProcessJob( string jobId, IStorageConnection connection, IJobPerformanceProcess process, CancellationToken shutdownToken) { var stateMachine = _context.StateMachineFactory.Create(connection); var processingState = new ProcessingState(_context.ServerId, _context.WorkerNumber); if (!stateMachine.TryToChangeState( jobId, processingState, new[] { EnqueuedState.StateName, ProcessingState.StateName })) { return; } // Checkpoint #3. Job is in the Processing state. However, there are // no guarantees that it was performed. We need to re-queue it even // it was performed to guarantee that it was performed AT LEAST once. // It will be re-queued after the JobTimeout was expired. IState state; try { var jobData = connection.GetJobData(jobId); jobData.EnsureLoaded(); var cancellationToken = new ServerJobCancellationToken( jobId, connection, _context, shutdownToken); var performContext = new PerformContext( _context, connection, jobId, jobData.Job, jobData.CreatedAt, cancellationToken); var latency = (DateTime.UtcNow - jobData.CreatedAt).TotalMilliseconds; var duration = Stopwatch.StartNew(); process.Run(performContext, jobData.Job); duration.Stop(); state = new SucceededState((long)latency, duration.ElapsedMilliseconds); } catch (OperationCanceledException) { throw; } catch (JobPerformanceException ex) { state = new FailedState(ex.InnerException) { Reason = ex.Message }; } catch (Exception ex) { state = new FailedState(ex) { Reason = "Internal Hangfire Server exception occurred. Please, report it to Hangfire developers." }; } // Ignore return value, because we should not do // anything when current state is not Processing. stateMachine.TryToChangeState(jobId, state, new[] { ProcessingState.StateName }); }
private IState PerformJob(BackgroundProcessContext context, IStorageConnection connection, string jobId) { try { var jobData = connection.GetJobData(jobId); if (jobData == null) { // Job expired just after moving to a processing state. This is an // unreal scenario, but shit happens. Returning null instead of throwing // an exception and rescuing from en-queueing a poisoned jobId back // to a queue. return(null); } jobData.EnsureLoaded(); var backgroundJob = new BackgroundJob(jobId, jobData.Job, jobData.CreatedAt); var jobToken = new ServerJobCancellationToken(connection, jobId, context.ServerId, _workerId, context.CancellationToken); var jobActivatorContext = new JobActivatorContext(connection, backgroundJob, jobToken); var scope = _activator.BeginScope(jobActivatorContext); if (scope != null) { using (scope) { var performContext = new PerformContext(connection, backgroundJob, jobToken, _profiler, scope); var latency = (DateTime.UtcNow - jobData.CreatedAt).TotalMilliseconds; var duration = Stopwatch.StartNew(); var result = _performer.Perform(performContext); duration.Stop(); return(new SucceededState(result, (long)latency, duration.ElapsedMilliseconds)); } } else { if (jobActivatorContext.ReEnqueueAt.HasValue) { return(new ScheduledState(jobActivatorContext.ReEnqueueAt.Value)); } else { return(new FailedState(new InvalidOperationException("Scope could not be started"))); } } } catch (JobAbortedException) { // Background job performance was aborted due to a // state change, so it's idenfifier should be removed // from a queue. return(null); } catch (JobPerformanceException ex) { return(new FailedState(ex.InnerException) { Reason = ex.Message }); } catch (Exception ex) { if (ex is OperationCanceledException && context.IsShutdownRequested) { throw; } return(new FailedState(ex) { Reason = "An exception occurred during processing of a background job." }); } }
internal PerformContext(PerformContext context) : this(context, context.Connection, context.JobId, context.Job, context.CreatedAt, context.JobExecutionContext) { Items = context.Items; }