protected override async Task <JobResult> RunInternalAsync(JobRunContext context) { var linkedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(context.CancellationToken, TimeSpan.FromSeconds(30).ToCancellationToken()); QueueEntry <T> queueEntry; try { queueEntry = await _queue.DequeueAsync(linkedCancellationToken.Token).AnyContext(); } catch (Exception ex) { return(JobResult.FromException(ex, $"Error trying to dequeue message: {ex.Message}")); } if (queueEntry == null) { return(JobResult.Success); } if (context.CancellationToken.IsCancellationRequested) { Logger.Info().Message($"Job was cancelled. Abandoning queue item: {queueEntry.Id}").Write(); await queueEntry.AbandonAsync().AnyContext(); return(JobResult.Cancelled); } using (var lockValue = await GetQueueEntryLockAsync(queueEntry, context.CancellationToken).AnyContext()) { if (lockValue == null) { return(JobResult.SuccessWithMessage("Unable to acquire queue item lock.")); } #if DEBUG Logger.Trace().Message($"Processing queue entry '{queueEntry.Id}'.").Write(); #endif try { var result = await ProcessQueueEntryAsync(new JobQueueEntryContext <T>(queueEntry, lockValue, context.CancellationToken)).AnyContext(); if (!AutoComplete) { return(result); } if (result.IsSuccess) { await queueEntry.CompleteAsync().AnyContext(); } else { await queueEntry.AbandonAsync().AnyContext(); } return(result); } catch { await queueEntry.AbandonAsync().AnyContext(); throw; } } }
public async Task <JobResult> RunAsync(CancellationToken cancellationToken = default(CancellationToken)) { IDisposable scope = new EmptyDisposable(); if (!_runningContinuous) { scope = _logger.BeginScope(s => s.Property("job", _jobName)); } using (scope) { _logger.Trace("Job run \"{0}\" starting...", _jobName); using (var lockValue = await GetJobLockAsync().AnyContext()) { if (lockValue == null) { return(JobResult.SuccessWithMessage("Unable to acquire job lock.")); } var result = await TryRunAsync(new JobRunContext(lockValue, cancellationToken)).AnyContext(); if (result != null) { if (!result.IsSuccess) { _logger.Error(result.Error, "Job run \"{0}\" failed: {1}", GetType().Name, result.Message); } else if (!String.IsNullOrEmpty(result.Message)) { _logger.Info("Job run \"{0}\" succeeded: {1}", GetType().Name, result.Message); } else { _logger.Trace("Job run \"{0}\" succeeded.", GetType().Name); } } else { _logger.Error("Null job run result for \"{0}\".", GetType().Name); } return(result); } } }
public async Task <JobResult> RunAsync(CancellationToken cancellationToken = default(CancellationToken)) { EnsureJobNameSet(); Logger.Trace().Logger(_jobName).Message("Job run \"{0}\" starting...", _jobName).Write(); using (var lockValue = await GetJobLockAsync().AnyContext()) { if (lockValue == null) { return(JobResult.SuccessWithMessage("Unable to acquire job lock.")); } var result = await TryRunAsync(new JobRunContext(lockValue, cancellationToken)).AnyContext(); if (result != null) { if (!result.IsSuccess) { Logger.Error().Logger(_jobName).Message("Job run \"{0}\" failed: {1}", GetType().Name, result.Message).Exception(result.Error).Write(); } else if (!String.IsNullOrEmpty(result.Message)) { Logger.Info().Logger(_jobName).Message("Job run \"{0}\" succeeded: {1}", GetType().Name, result.Message).Write(); } else { Logger.Trace().Logger(_jobName).Message("Job run \"{0}\" succeeded.", GetType().Name).Write(); } } else { Logger.Error().Logger(_jobName).Message("Null job run result for \"{0}\".", GetType().Name).Write(); } return(result); } }
protected async override Task <JobResult> ProcessQueueEntryAsync(JobQueueEntryContext <WorkItemData> context) { var workItemDataType = Type.GetType(context.QueueEntry.Value.Type); if (workItemDataType == null) { return(JobResult.FailedWithMessage("Could not resolve work item data type.")); } object workItemData; try { workItemData = await _queue.Serializer.DeserializeAsync(context.QueueEntry.Value.Data, workItemDataType).AnyContext(); } catch (Exception ex) { return(JobResult.FromException(ex, "Failed to parse work item data.")); } var handler = _handlers.GetHandler(workItemDataType); if (handler == null) { return(JobResult.FailedWithMessage($"Handler for type {workItemDataType.Name} not registered.")); } if (context.QueueEntry.Value.SendProgressReports) { await _messageBus.PublishAsync(new WorkItemStatus { WorkItemId = context.QueueEntry.Value.WorkItemId, Progress = 0, Type = context.QueueEntry.Value.Type }).AnyContext(); } using (var lockValue = await handler.GetWorkItemLockAsync(workItemData, context.CancellationToken).AnyContext()) { if (lockValue == null) { return(JobResult.SuccessWithMessage("Unable to acquire work item lock.")); } var progressCallback = new Func <int, string, Task>(async(progress, message) => { if (handler.AutoRenewLockOnProgress && lockValue != null) { await lockValue.RenewAsync().AnyContext(); } await _messageBus.PublishAsync(new WorkItemStatus { WorkItemId = context.QueueEntry.Value.WorkItemId, Progress = progress, Message = message, Type = context.QueueEntry.Value.Type }).AnyContext(); }); try { _logger.Info("Processing {0} work item queue entry ({1}).", workItemDataType.Name, context.QueueEntry.Id); await handler.HandleItemAsync(new WorkItemContext(context, workItemData, JobId, lockValue, progressCallback)).AnyContext(); } catch (Exception ex) { await context.QueueEntry.AbandonAsync().AnyContext(); _logger.Error("Error processing {0} work item queue entry ({1}).", workItemDataType.Name, context.QueueEntry.Id); return(JobResult.FromException(ex, $"Error in handler {workItemDataType.Name}.")); } await context.QueueEntry.CompleteAsync().AnyContext(); _logger.Info("Completed {0} work item queue entry ({1}).", workItemDataType.Name, context.QueueEntry.Id); if (context.QueueEntry.Value.SendProgressReports) { await _messageBus.PublishAsync(new WorkItemStatus { WorkItemId = context.QueueEntry.Value.WorkItemId, Progress = 100, Type = context.QueueEntry.Value.Type }).AnyContext(); } return(JobResult.Success); } }