Exemple #1
0
        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);
            }
        }
Exemple #3
0
        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)));
        }
Exemple #4
0
        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));
        }
Exemple #9
0
        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();
        }
Exemple #10
0
        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));
 }