public WorkItemContext(JobQueueEntryContext <WorkItemData> context, object data, string jobId, ILock workItemLock, Func <int, string, Task> progressCallback) : base(context.QueueEntry, context.QueueEntryLock, context.CancellationToken) { Data = data; JobId = jobId; WorkItemLock = workItemLock; _progressCallback = progressCallback; }
protected abstract Task <JobResult> ProcessQueueEntryAsync(JobQueueEntryContext <T> context);
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); } }