Beispiel #1
0
        public override async Task AbandonAsync(IQueueItem <TData> item)
        {
            EnsureArg.IsNotNull(item, nameof(item));
            EnsureArg.IsNotNullOrEmpty(item.Id, nameof(item.Id));
            this.logger.LogDebug($"queue item abandon (id={item.Id}, queue={this.options.Name})");

            if (item.IsAbandoned || item.IsCompleted)
            {
                throw new InvalidOperationException($"queue item has already been completed or abandoned (id={item.Id})");
            }

            var message = this.ToMessage(item);

            if (message.DequeueCount > this.options.Retries)
            {
                // too many retries
                await Task.WhenAll(
                    this.queue.DeleteMessageAsync(message),
                    this.deadletterQueue.AddMessageAsync(message)).AnyContext();
            }
            else
            {
                await this.queue.UpdateMessageAsync(message, TimeSpan.Zero, MessageUpdateFields.Visibility).AnyContext(); // item available immediately
            }

            Interlocked.Increment(ref this.abandonedCount);
            item.MarkAbandoned();

            this.logger.LogJournal(LogKeys.Queueing, $"item abandoned (id={item.Id}, queue={this.options.Name}, type={typeof(TData).PrettyName()})", LogEventPropertyKeys.TrackDequeue);
            this.LastDequeuedDate = DateTime.UtcNow;
        }
Beispiel #2
0
        public override Task AbandonAsync(IQueueItem <TData> item)
        {
            EnsureArg.IsNotNull(item, nameof(item));
            EnsureArg.IsNotNullOrEmpty(item.Id, nameof(item.Id));
            this.Logger.LogDebug($"{{LogKey:l}} queue item abandon (id={item.Id}, queue={this.Options.QueueName})", LogKeys.Queueing);

            if (item.IsAbandoned || item.IsCompleted)
            {
                throw new InvalidOperationException($"queue item has already been completed or abandoned (id={item.Id})");
            }

            var tag = item.Properties.GetValueOrDefault <ulong>("DeliveryTag");

            if (tag > 0)
            {
                this.channel.BasicNack(tag, false, false);
                Interlocked.Increment(ref this.abandonedCount);
                item.MarkAbandoned();

                this.Logger.LogJournal(LogKeys.Queueing, $"queue item abandoned: {typeof(TData).PrettyName()} (id={item.Id}, queue={this.Options.QueueName})", LogPropertyKeys.TrackDequeue);
                this.LastDequeuedDate = DateTime.UtcNow;
            }

            return(Task.CompletedTask);
        }
Beispiel #3
0
        public override Task AbandonAsync(IQueueItem <TData> item)
        {
            EnsureArg.IsNotNull(item, nameof(item));
            EnsureArg.IsNotNullOrEmpty(item.Id, nameof(item.Id));
            this.Logger.LogDebug($"{{LogKey:l}} queue item abandon (id={item.Id}, queue={this.Options.QueueName})", LogKeys.Queueing);

            if (item.IsAbandoned || item.IsCompleted)
            {
                throw new InvalidOperationException($"queue item has already been completed or abandoned (id={item.Id})");
            }

#pragma warning disable CA2000  // Dispose objects before losing scope
#pragma warning disable IDE0068 // Use recommended dispose pattern
            if (!this.dequeued.TryRemove(item.Id, out var dequeuedItem) || dequeuedItem == null)
#pragma warning restore IDE0068 // Use recommended dispose pattern
#pragma warning restore CA2000  // Dispose objects before losing scope
            {
                throw new Exception($"unable to remove item from the dequeued list, not found (id={item.Id})");
            }

            if (dequeuedItem.Attempts < this.Options.Retries + 1)
            {
                if (this.Options.RetryDelay > TimeSpan.Zero)
                {
                    this.Logger.LogDebug($"{{LogKey:l}} add item to wait list, for future retry (id={item.Id})", LogKeys.Queueing);
                    var unawaited = Run.DelayedAsync(
                        this.GetRetryDelay(dequeuedItem.Attempts), () =>
                    {
                        this.queue.Enqueue(dequeuedItem);
                        return(Task.CompletedTask);
                    });
                }
                else
                {
                    this.Logger.LogDebug($"{{LogKey:l}} add item back to queue, for retry (id={item.Id})", LogKeys.Queueing);
                    var unawaited = Task.Run(() => this.queue.Enqueue(dequeuedItem));
                }
            }
            else
            {
                this.Logger.LogDebug($"retry limit exceeded, moving to deadletter (id={item.Id})");
                this.deadletterQueue.Enqueue(dequeuedItem);
            }

            Interlocked.Increment(ref this.abandonedCount);
            item.MarkAbandoned();

            this.Logger.LogJournal(LogKeys.Queueing, $"queue item abandoned: {typeof(TData).PrettyName()} (id={item.Id}, queue={this.Options.QueueName})", LogPropertyKeys.TrackDequeue);
            this.LastDequeuedDate = DateTime.UtcNow;
            return(Task.CompletedTask);
        }
Beispiel #4
0
        public override Task AbandonAsync(IQueueItem <TData> item)
        {
            EnsureArg.IsNotNull(item, nameof(item));
            EnsureArg.IsNotNullOrEmpty(item.Id, nameof(item.Id));
            this.logger.LogDebug($"queue item abandon (id={item.Id}, queue={this.options.Name})");

            if (item.IsAbandoned || item.IsCompleted)
            {
                throw new InvalidOperationException($"queue item has already been completed or abandoned (id={item.Id})");
            }

            if (!this.dequeued.TryRemove(item.Id, out var dequeuedItem) || dequeuedItem == null)
            {
                throw new Exception($"unable to remove item from the dequeued list, not found (id={item.Id})");
            }

            if (dequeuedItem.Attempts < this.options.Retries + 1)
            {
                if (this.options.RetryDelay > TimeSpan.Zero)
                {
                    this.logger.LogDebug($"add item to wait list, for future retry (id={item.Id})");
                    var unawaited = Run.DelayedAsync(
                        this.GetRetryDelay(dequeuedItem.Attempts), () =>
                    {
                        this.queue.Enqueue(dequeuedItem);
                        return(Task.CompletedTask);
                    });
                }
                else
                {
                    this.logger.LogDebug($"add item back to queue, for retry (id={item.Id})");
                    var unawaited = Task.Run(() => this.queue.Enqueue(dequeuedItem));
                }
            }
            else
            {
                this.logger.LogDebug($"retry limit exceeded, moving to deadletter (id={item.Id})");
                this.deadletterQueue.Enqueue(dequeuedItem);
            }

            Interlocked.Increment(ref this.abandonedCount);
            item.MarkAbandoned();

            this.logger.LogJournal(LogEventPropertyKeys.TrackDequeue, $"{{LogKey:l}} item abandoned (id={item.Id}, queue={this.options.Name}, type={typeof(TData).PrettyName()})", args: new[] { LogEventKeys.Queueing });
            this.LastDequeuedDate = DateTime.UtcNow;
            return(Task.CompletedTask);
        }