public void ShouldWaitForWorkCompleteWhereAllWorkersAreBlockedOnRingBuffer()
        {
            long expectedNumberMessages = 10;

            fillRingBuffer(expectedNumberMessages);

            var workers = new StubConsumer[3];

            for (int i = 0, size = workers.Length; i < size; i++)
            {
                workers[i]          = new StubConsumer(0);
                workers[i].Sequence = (expectedNumberMessages - 1);
            }

            IConsumerBarrier consumerBarrier = ringBuffer.CreateConsumerBarrier(workers);
            ThreadStart      runnable        = () =>
            {
                StubEntry entry = producerBarrier.NextEntry();
                entry.Value = ((int)entry.Sequence);
                producerBarrier.Commit(entry);

                foreach (StubConsumer stubWorker in workers)
                {
                    stubWorker.Sequence = (entry.Sequence);
                }
            };


            new Thread(runnable).Start();

            long expectedWorkSequence  = expectedNumberMessages;
            long completedWorkSequence = consumerBarrier.WaitFor(expectedNumberMessages);

            Assert.IsTrue(completedWorkSequence >= expectedWorkSequence);
        }
        public void ShouldWaitForWorkCompleteWhereCompleteWorkThresholdIsBehind()
        {
            long expectedNumberMessages = 10;

            fillRingBuffer(expectedNumberMessages);

            var entryConsumers = new StubConsumer[3];

            for (int i = 0, size = entryConsumers.Length; i < size; i++)
            {
                entryConsumers[i]          = new StubConsumer(0);
                entryConsumers[i].Sequence = (expectedNumberMessages - 2);
            }

            IConsumerBarrier consumerBarrier = ringBuffer.CreateConsumerBarrier(entryConsumers);

            ThreadStart runnable = () =>
            {
                foreach (StubConsumer stubWorker in entryConsumers)
                {
                    stubWorker.Sequence += 1;
                }
            };


            new Thread(runnable).Start();

            long expectedWorkSequence  = expectedNumberMessages - 1;
            long completedWorkSequence = consumerBarrier.WaitFor(expectedWorkSequence);

            Assert.IsTrue(completedWorkSequence >= expectedWorkSequence);
        }
        public List <StubEntry> Call()
        {
            latch.Set();
            consumerBarrier.WaitFor(toWaitForSequence);

            List <StubEntry> retval = new List <StubEntry>();

            for (long l = initialSequence; l <= toWaitForSequence; l++)
            {
                retval.Add(consumerBarrier.GetEntry(l));
            }
            return(retval);
        }
Beispiel #4
0
        /// <summary>
        /// It is ok to have another thread rerun this method after a halt().
        /// </summary>
        public void Run()
        {
            _running.Data = true;

            OnStart();

            var nextSequence = Sequence + 1;

            while (_running.Data)
            {
                var waitForResult = _consumerBarrier.WaitFor(nextSequence);
                if (!waitForResult.IsAlerted)
                {
                    var availableSequence = waitForResult.AvailableSequence;
                    while (nextSequence <= availableSequence)
                    {
                        T data = _consumerBarrier.GetEntry(nextSequence);
                        _handler.OnAvailable(nextSequence, data);

                        nextSequence++;
                    }
                    _handler.OnEndOfBatch();

                    if (_delaySequenceWrite)
                    {
                        if (nextSequence > _nextSequencePublish)
                        {
                            Sequence              = nextSequence - 1; // volatile write
                            _nextSequencePublish += _sequenceUpdatePeriod;
                        }
                    }
                    else
                    {
                        Sequence = nextSequence - 1; // volatile write
                    }
                }
            }

            OnStop();
        }
        public void ShouldClaimAndGet()
        {
            Assert.AreEqual(-1L, ringBuffer.Cursor);

            var expectedEntry = new StubEntry(2701);

            StubEntry oldEntry = producerBarrier.NextEntry();

            oldEntry.copy(expectedEntry);
            producerBarrier.Commit(oldEntry);

            long sequence = consumerBarrier.WaitFor(0);

            Assert.AreEqual(0, sequence);

            StubEntry entry = ringBuffer.GetEntry(sequence);

            Assert.AreEqual(expectedEntry, entry);

            Assert.AreEqual(0L, ringBuffer.Cursor);
        }