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; }
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); }
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); }
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); }