Пример #1
0
        public AsyncEventWorkerTests()
        {
            asyncEventQueueManager = Substitute.For <IAsyncEventQueueManager>();
            serviceLocator         = Substitute.For <IServiceLocator>();
            sut = new AsyncEventWorker(asyncEventQueueManager, serviceLocator);

            asyncEventQueueManager.GetQueueStateAsync("queue").Returns(ci => queueState);
            asyncEventQueueManager.GetQueueEventsAsync("queue").Returns(ci => events);
            serviceLocator.GetAll(typeof(IAsyncEventListener <Event1>)).Returns(ci => listeners);

            listeners.Add(Substitute.For <IAsyncEventListener <Event1> >());
            listeners.Add(Substitute.For <IAsyncEventListener <Event1> >());
            listeners[0].EventSequencer.Returns(Substitute.For <IAsyncEventSequencer <Event1> >());
            listeners[1].EventSequencer.Returns(Substitute.For <IAsyncEventSequencer <Event1> >());

            listeners[0].EventSequencer.GetEventSequencing(null).ReturnsForAnyArgs(new List <EventSequencing>()
            {
                new EventSequencing()
                {
                    EventSequenceNumber = 0 /* shouldn't be important now */, SequenceName = "queue"
                }
            });

            listeners[1].EventSequencer.GetEventSequencing(null).ReturnsForAnyArgs(new List <EventSequencing>()
            {
                new EventSequencing()
                {
                    EventSequenceNumber = 0 /* shouldn't be important now */, SequenceName = "queue"
                }
            });
        }
Пример #2
0
        public async Task RunQueueBacklogAsync(string queueName)
        {
            IAsyncEventQueueState queue = await asyncEventQueueManager.GetQueueStateAsync(queueName);

            if (queue == null)
            {
                return;
            }

            IReadOnlyCollection <IAsyncEventQueueRecord> records = await asyncEventQueueManager.GetQueueEventsAsync(queueName);

            if (records.Count == 0)
            {
                return;
            }

            bool processOnlyNonsequential = false;

            var nonSequential = records.Where(x => x.SequenceNumber == null).ToList();
            var sequential    = records.Where(x => x.SequenceNumber != null).ToList();

            long?firstSequenceNumber = sequential.FirstOrDefault()?.SequenceNumber;  //records should always arrive in order, but possibly with gaps in sequence
            long?lastSequenceNumber  = sequential.LastOrDefault()?.SequenceNumber;

            Logger.Trace($"Read {records.Count} async events from queue '{queueName}', last sequence number {lastSequenceNumber}");

            if (firstSequenceNumber != null &&
                queue.LastSequenceNumberProcessed != null &&
                (queue.LastSequenceNumberProcessed != firstSequenceNumber.Value - 1 ||
                 queue.LastSequenceNumberProcessed.Value + sequential.Count != lastSequenceNumber))
            {
                bool anyNonsequential = nonSequential.Any();
                if (anyNonsequential)
                {
                    Logger.Debug($"Processing only non-sequential async events in '{queueName}' queue: missing some events in sequence at #{queue.LastSequenceNumberProcessed.Value + 1}");
                    processOnlyNonsequential = true;
                }
                else
                {
                    string error = $"Skipping processing of '{queueName}' async event queue: missing events in sequence at #{queue.LastSequenceNumberProcessed.Value + 1}";
                    Logger.Warn(error);
                    throw new AsyncEventProcessingSequenceException(error, queue.LastSequenceNumberProcessed.Value + 1);
                }
            }

            if (nonSequential.Count > 0)
            {
                await ProcessEventsAsync(nonSequential, queueName);
            }

            if (!processOnlyNonsequential)
            {
                if (sequential.Count > 0)
                {
                    await ProcessEventsAsync(sequential, queueName);
                }
            }

            if (processOnlyNonsequential)
            {
                throw new AsyncEventProcessingSequenceException(
                          $"Processed only non-sequential async events in '{queueName}' queue: missing some events in sequence at #{queue.LastSequenceNumberProcessed.Value + 1}",
                          queue.LastSequenceNumberProcessed.Value + 1);
            }
        }