public async Task <int> CompleteBatch(int number)
        {
            Interlocked.Exchange(ref processedMessages, 0);

            Start(number);
            do
            {
                await Task.Delay(100);
            }while (processedMessages < messageCount && !messageProcessing.IsCancellationRequested);

            if (messageProcessing.IsCancellationRequested)
            {
                logger.LogError("The migration was cancelled due to error when completing the batch.");
            }

            if (!messageProcessing.IsCancellationRequested && QueueCreator.GetStagingQueueMessageLength(consumer.Model) > 0)
            {
                throw new InvalidOperationException("Staging queue is not empty after finishing CompleteBatch");
            }

            channel.WaitForConfirms(TimeSpan.FromSeconds(10));

            await Stop();

            return(processedMessages);
        }
예제 #2
0
        void PurgueQueueIfNotEmpty(IModel model)
        {
            var statingQueueMessageLength = QueueCreator.GetStagingQueueMessageLength(model);

            if (statingQueueMessageLength > 0)
            {
                logger.LogWarning("Purging staging queue - staging queue contains messages.");
                QueueCreator.PurgeStagingQueue(model);
            }
        }
        void EnsureStagingQueueIsEmpty()
        {
            using var connection = factory.CreateConnection();
            using var model      = connection.CreateModel();
            var stagingQueueLength = QueueCreator.GetStagingQueueMessageLength(model);

            if (stagingQueueLength > 0)
            {
                throw new Exception(
                          $"Unable to complete migration as there are still messages available in the staging queue. Found {stagingQueueLength} messages.");
            }
        }
예제 #4
0
        public Task <int> WriteTimeoutsToStagingQueue(IReadOnlyList <TimeoutData> timeouts, string stageExchangeName)
        {
            int messageCount;

            using (var connection = GetConnection(rabbitConnectionString))
            {
                using (var model = connection.CreateModel())
                {
                    PurgueQueueIfNotEmpty(model);
                    model.ConfirmSelect();
                    foreach (var timeout in timeouts)
                    {
                        PublishTimeout(model, timeout, stageExchangeName);
                    }

                    model.WaitForConfirmsOrDie(TimeSpan.FromSeconds(30));
                    messageCount = Convert.ToInt32(QueueCreator.GetStagingQueueMessageLength(model));
                }
            }

            return(Task.FromResult(messageCount));
        }
        public void Start(int batchNumber)
        {
            messageProcessing = new CancellationTokenSource();

            connection = factory.CreateConnection("TimoutMigration - CompleteBatch");

            channel = connection.CreateModel();

            channel.ConfirmSelect();
            messageCount = QueueCreator.GetStagingQueueMessageLength(channel);

            logger.LogDebug($"Pushing {messageCount} to the native timeout structure");
            var prefetchCount = (long)MaxConcurrency * prefetchMultiplier;

            channel.BasicQos(0, (ushort)Math.Min(prefetchCount, ushort.MaxValue), false);

            consumer = new AsyncEventingBasicConsumer(channel);

            connection.ConnectionShutdown += Connection_ConnectionShutdown;

            consumer.Received += Consumer_Received;

            channel.BasicConsume(queueName, false, $"Batch-{batchNumber}", consumer);
        }
 void DeleteStagingQueue()
 {
     using var connection = factory.CreateConnection();
     using var channel    = connection.CreateModel();
     QueueCreator.DeleteStagingInfrastructure(channel);
 }