예제 #1
0
 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;
 }
예제 #2
0
 protected abstract Task <JobResult> ProcessQueueEntryAsync(JobQueueEntryContext <T> context);
예제 #3
0
        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);
            }
        }