private void OnMessageConfirmation(MessageConfirmationEvent @event) { ConcurrentDictionary <ulong, TaskCompletionSource <object> > requests; if (!unconfirmedChannelRequests.TryGetValue(@event.Channel, out requests)) { return; } var deliveryTag = @event.DeliveryTag; var multiple = @event.Multiple; var isNack = @event.IsNack; if (multiple) { // Fix me: ConcurrentDictionary.Keys acquires all locks, it is very expensive operation and could perform slowly. foreach (var sequenceNumber in requests.Keys.Where(x => x <= deliveryTag)) { TaskCompletionSource <object> confirmation; if (requests.TryGetValue(sequenceNumber, out confirmation)) { Confirm(confirmation, sequenceNumber, isNack); } } } else { TaskCompletionSource <object> confirmation; if (requests.TryGetValue(deliveryTag, out confirmation)) { Confirm(confirmation, deliveryTag, isNack); } } }
private void OnMessageConfirmation(MessageConfirmationEvent @event) { if (!unconfirmedChannelRequests.TryGetValue(@event.Channel.ChannelNumber, out var requests)) { return; } var deliveryTag = @event.DeliveryTag; var multiple = @event.Multiple; var type = @event.IsNack ? ConfirmationType.Nack : ConfirmationType.Ack; if (multiple) { foreach (var sequenceNumber in requests.Select(x => x.Key)) { if (sequenceNumber <= deliveryTag && requests.TryRemove(sequenceNumber, out var confirmationTcs)) { Confirm(confirmationTcs, sequenceNumber, type); } } } else if (requests.TryRemove(deliveryTag, out var confirmation)) { Confirm(confirmation, deliveryTag, type); } }
public void Should_fail_with_nack_confirmation_event() { model.NextPublishSeqNo.Returns(DeliveryTag); var publishConfirmationWaiter = publishConfirmationListener.GetWaiter(model); eventBus.Publish(MessageConfirmationEvent.Nack(model, DeliveryTag, false)); Assert.Throws <PublishNackedException>(() => publishConfirmationWaiter.Wait(TimeSpan.FromMilliseconds(10))); }
public void Should_success_with_ack_confirmation_event() { model.NextPublishSeqNo.Returns(DeliveryTag); var publishConfirmationWaiter = publishConfirmationListener.GetWaiter(model); eventBus.Publish(MessageConfirmationEvent.Ack(model, DeliveryTag, false)); publishConfirmationWaiter.Wait(TimeSpan.FromMilliseconds(10)); }
public async Task Should_success_with_ack_confirmation_event() { model.NextPublishSeqNo.Returns(DeliveryTag); var confirmation = publishConfirmationListener.CreatePendingConfirmation(model); eventBus.Publish(MessageConfirmationEvent.Ack(model, DeliveryTag, false)); await confirmation.WaitAsync().ConfigureAwait(false); }
public async Task Should_fail_with_nack_confirmation_event() { model.NextPublishSeqNo.Returns(DeliveryTag); var confirmation = publishConfirmationListener.CreatePendingConfirmation(model); eventBus.Publish(MessageConfirmationEvent.Nack(model, DeliveryTag, false)); await Assert.ThrowsAsync <PublishNackedException>( () => confirmation.WaitAsync() ).ConfigureAwait(false); }
public void Should_fail_with_multiple_nack_confirmation_event() { model.Expect(x => x.NextPublishSeqNo).Return(DeliveryTag - 1); model.Expect(x => x.NextPublishSeqNo).Return(DeliveryTag); var publishConfirmationWaiter1 = publishConfirmationListener.GetWaiter(model); var publishConfirmationWaiter2 = publishConfirmationListener.GetWaiter(model); eventBus.Publish(MessageConfirmationEvent.Nack(model, DeliveryTag, true)); Assert.Throws <PublishNackedException>(() => publishConfirmationWaiter1.Wait(TimeSpan.FromMilliseconds(10))); Assert.Throws <PublishNackedException>(() => publishConfirmationWaiter2.Wait(TimeSpan.FromMilliseconds(10))); }
public void Should_success_with_multiple_ack_confirmation_event() { model.Expect(x => x.NextPublishSeqNo).Return(DeliveryTag - 1); model.Expect(x => x.NextPublishSeqNo).Return(DeliveryTag); var publishConfirmationWaiter1 = publishConfirmationListener.GetWaiter(model); var publishConfirmationWaiter2 = publishConfirmationListener.GetWaiter(model); eventBus.Publish(MessageConfirmationEvent.Ack(model, DeliveryTag, true)); publishConfirmationWaiter1.Wait(TimeSpan.FromMilliseconds(10)); publishConfirmationWaiter2.Wait(TimeSpan.FromMilliseconds(10)); }
public async Task Should_success_with_multiple_ack_confirmation_event() { model.NextPublishSeqNo.Returns(DeliveryTag - 1, DeliveryTag); var confirmation1 = publishConfirmationListener.CreatePendingConfirmation(model); var confirmation2 = publishConfirmationListener.CreatePendingConfirmation(model); eventBus.Publish(MessageConfirmationEvent.Ack(model, DeliveryTag, true)); await confirmation1.WaitAsync(); await confirmation2.WaitAsync(); }
public void Should_work_after_reconnection() { model.NextPublishSeqNo.Returns(DeliveryTag); var publishConfirmationWaiter1 = publishConfirmationListener.GetWaiter(model); eventBus.Publish(new PublishChannelCreatedEvent(model)); Assert.Throws <PublishInterruptedException>(() => publishConfirmationWaiter1.Wait(TimeSpan.FromMilliseconds(50))); var publishConfirmationWaiter2 = publishConfirmationListener.GetWaiter(model); eventBus.Publish(MessageConfirmationEvent.Ack(model, DeliveryTag, false)); publishConfirmationWaiter2.Wait(TimeSpan.FromMilliseconds(50)); }
public async Task Should_work_after_reconnection() { model.NextPublishSeqNo.Returns(DeliveryTag); var confirmation1 = publishConfirmationListener.CreatePendingConfirmation(model); eventBus.Publish(new ChannelRecoveredEvent(model)); await Assert.ThrowsAsync <PublishInterruptedException>( () => confirmation1.WaitAsync() ).ConfigureAwait(false); var confirmation2 = publishConfirmationListener.CreatePendingConfirmation(model); eventBus.Publish(MessageConfirmationEvent.Ack(model, DeliveryTag, false)); await confirmation2.WaitAsync().ConfigureAwait(false); }
private void OnNack(object sender, BasicNackEventArgs args) { eventBus.Publish(MessageConfirmationEvent.Nack((IModel)sender, args.DeliveryTag, args.Multiple)); }