Пример #1
0
        private void ProcessItems(Func <IQueueItem <TData>, CancellationToken, Task> handler, bool autoComplete, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(handler, nameof(handler));
            var linkedCancellationToken = this.CreateLinkedTokenSource(cancellationToken);

#pragma warning disable CA2016 // Forward the 'CancellationToken' parameter to methods that take one
            Task.Run(async() =>
            {
                this.Logger.LogInformation($"{{LogKey:l}} processing started (queue={this.Options.QueueName}, type={this.GetType().PrettyName()})", args: new[] { LogKeys.Queueing });
                while (!linkedCancellationToken.IsCancellationRequested)
                {
                    IQueueItem <TData> item = null;
                    try
                    {
                        item = await this.DequeueWithIntervalAsync(linkedCancellationToken.Token).AnyContext();
                    }
                    catch (Exception ex)
                    {
                        this.Logger.LogError(ex, $"{{LogKey:l}} processing error: {ex.Message}", args: new[] { LogKeys.Queueing });
                    }

                    if (linkedCancellationToken.IsCancellationRequested || item == null)
                    {
                        await Task.Delay(this.Options.ProcessInterval, linkedCancellationToken.Token).AnyContext();
                        continue;
                    }

                    using (this.Logger.BeginScope(new Dictionary <string, object>
                    {
                        [LogPropertyKeys.CorrelationId] = item.CorrelationId,
                    }))
                        using (var scope = this.Options.Tracer?.BuildSpan($"dequeue {this.Options.QueueName}", LogKeys.Queueing, SpanKind.Consumer, new Span(item.TraceId, item.SpanId)).Activate(this.Logger))
                        {
                            try
                            {
                                await handler(item, linkedCancellationToken.Token).AnyContext();
                                if (autoComplete && !item.IsAbandoned && !item.IsCompleted)
                                {
                                    await item.CompleteAsync().AnyContext();
                                }
                            }
                            catch (Exception ex)
                            {
                                Interlocked.Increment(ref this.workerErrorCount);
                                scope.Span.SetStatus(SpanStatus.Failed, ex.GetFullMessage());
                                this.Logger.LogError(ex, $"{{LogKey:l}} queue processing failed: {ex.GetFullMessage()}", args: new[] { LogKeys.Queueing });

                                if (!item.IsAbandoned && !item.IsCompleted)
                                {
                                    await item.AbandonAsync().AnyContext();
                                }
                            }
                        }
                }

                this.Logger.LogDebug($"{{LogKey:l}} queue processing exiting (name={this.Options.QueueName}, cancellation={linkedCancellationToken.IsCancellationRequested})", LogKeys.Queueing);
            }, linkedCancellationToken.Token)
            .ContinueWith(t => linkedCancellationToken.Dispose());
#pragma warning restore CA2016 // Forward the 'CancellationToken' parameter to methods that take one
        }
Пример #2
0
        private void ProcessItems(Func <IQueueItem <TData>, CancellationToken, Task> handler, bool autoComplete, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(handler, nameof(handler));
            var linkedCancellationToken = this.CreateLinkedTokenSource(cancellationToken);

            Task.Run(async() =>
            {
                this.logger.LogInformation($"{{LogKey:l}} processing started (queue={this.options.Name}, type={this.GetType().PrettyName()})", args: new[] { LogKeys.Queueing });
                while (!linkedCancellationToken.IsCancellationRequested)
                {
                    IQueueItem <TData> item = null;
                    try
                    {
                        item = await this.DequeueWithIntervalAsync(linkedCancellationToken.Token).AnyContext();
                    }
                    catch (Exception ex)
                    {
                        this.logger.LogError(ex, $"{{LogKey:l}} processing error: {ex.Message}", args: new[] { LogKeys.Queueing });
                    }

                    if (linkedCancellationToken.IsCancellationRequested || item == null)
                    {
                        continue;
                    }

                    using (this.logger.BeginScope(new Dictionary <string, object>
                    {
                        [LogEventPropertyKeys.CorrelationId] = item.Data.As <IHaveCorrelationId>()?.CorrelationId,
                    }))
                    {
                        try
                        {
                            await handler(item, linkedCancellationToken.Token).AnyContext();
                            if (autoComplete && !item.IsAbandoned && !item.IsCompleted)
                            {
                                await item.CompleteAsync().AnyContext();
                            }
                        }
                        catch (Exception ex)
                        {
                            Interlocked.Increment(ref this.workerErrorCount);
                            this.logger.LogError(ex, $"{{LogKey:l}} processing error: {ex.Message}", args: new[] { LogKeys.Queueing });

                            if (!item.IsAbandoned && !item.IsCompleted)
                            {
                                await item.AbandonAsync().AnyContext();
                            }
                        }
                    }
                }

                this.logger.LogDebug($"queue processing exiting (name={this.options.Name}, cancellation={linkedCancellationToken.IsCancellationRequested})");
            }, linkedCancellationToken.Token)
            .ContinueWith(t => linkedCancellationToken.Dispose());
        }