Exemple #1
0
        /// <summary>
        /// Poll for new messages in a stream. If new messages are found beyond the last consumed position then they
        /// will be delivered to the <seealso cref="IBlockHandler"/> up to a limited number of bytes.
        ///
        /// A scan will terminate if a padding frame is encountered. If first frame in a scan is padding then a block
        /// for the padding is notified. If the padding comes after the first frame in a scan then the scan terminates
        /// at the offset the padding frame begins. Padding frames are delivered singularly in a block.
        ///
        /// Padding frames may be for a greater range than the limit offset but only the header needs to be valid so
        /// relevant length of the frame is <see cref="DataHeaderFlyweight.HEADER_LENGTH"/>
        /// </summary>
        /// <param name="handler">     to which block is delivered. </param>
        /// <param name="blockLengthLimit"> up to which a block may be in length. </param>
        /// <returns> the number of bytes that have been consumed. </returns>
        public int BlockPoll(BlockHandler handler, int blockLengthLimit)
        {
            if (_isClosed)
            {
                return(0);
            }

            var position        = _subscriberPosition.Get();
            var offset          = (int)position & _termLengthMask;
            var termBuffer      = ActiveTermBuffer(position);
            var limitOffset     = Math.Min(offset + blockLengthLimit, termBuffer.Capacity);
            var resultingOffset = TermBlockScanner.Scan(termBuffer, offset, limitOffset);
            var length          = resultingOffset - offset;

            if (resultingOffset > offset)
            {
                try
                {
                    var termId = termBuffer.GetInt(offset + DataHeaderFlyweight.TERM_ID_FIELD_OFFSET);

                    handler(termBuffer, offset, length, SessionId, termId);
                }
                catch (Exception t)
                {
                    _errorHandler(t);
                }
                finally
                {
                    _subscriberPosition.SetOrdered(position + length);
                }
            }

            return(length);
        }
Exemple #2
0
        public void ShouldReadBlockOfThreeMessagesThatFillBuffer()
        {
            const int offset               = 0;
            int       limit                = _termBuffer.Capacity;
            const int messageLength        = 50;
            int       alignedMessageLength = BitUtil.Align(messageLength, FrameDescriptor.FRAME_ALIGNMENT);
            int       thirdMessageLength   = limit - (alignedMessageLength * 2);

            A.CallTo(() => _termBuffer.GetIntVolatile(FrameDescriptor.LengthOffset(offset)))
            .Returns(messageLength);
            A.CallTo(() => _termBuffer.GetShort(FrameDescriptor.TypeOffset(offset)))
            .Returns((short)HeaderFlyweight.HDR_TYPE_DATA);
            A.CallTo(() => _termBuffer.GetIntVolatile(FrameDescriptor.LengthOffset(alignedMessageLength)))
            .Returns(messageLength);
            A.CallTo(() => _termBuffer.GetShort(FrameDescriptor.TypeOffset(alignedMessageLength)))
            .Returns((short)HeaderFlyweight.HDR_TYPE_DATA);
            A.CallTo(() => _termBuffer.GetIntVolatile(FrameDescriptor.LengthOffset(alignedMessageLength * 2)))
            .Returns(thirdMessageLength);
            A.CallTo(() => _termBuffer.GetShort(FrameDescriptor.TypeOffset(alignedMessageLength * 2)))
            .Returns((short)HeaderFlyweight.HDR_TYPE_DATA);

            int newOffset = TermBlockScanner.Scan(_termBuffer, offset, limit);

            Assert.That(newOffset, Is.EqualTo(limit));
        }
Exemple #3
0
        /// <summary>
        /// Poll for new messages in a stream. If new messages are found beyond the last consumed position then they
        /// will be delivered to the <seealso cref="IBlockHandler"/> up to a limited number of bytes.
        /// </summary>
        /// <param name="blockHandler">     to which block is delivered. </param>
        /// <param name="blockLengthLimit"> up to which a block may be in length. </param>
        /// <returns> the number of bytes that have been consumed. </returns>
        public int BlockPoll(IBlockHandler blockHandler, int blockLengthLimit)
        {
            if (_isClosed)
            {
                return(0);
            }

            var position   = _subscriberPosition.Get();
            var termOffset = (int)position & _termLengthMask;
            var termBuffer = ActiveTermBuffer(position);
            var limit      = Math.Min(termOffset + blockLengthLimit, termBuffer.Capacity);

            var resultingOffset = TermBlockScanner.Scan(termBuffer, termOffset, limit);

            var bytesConsumed = resultingOffset - termOffset;

            if (resultingOffset > termOffset)
            {
                try
                {
                    var termId = termBuffer.GetInt(termOffset + DataHeaderFlyweight.TERM_ID_FIELD_OFFSET);

                    blockHandler.OnBlock(termBuffer, termOffset, bytesConsumed, SessionId, termId);
                }
                catch (Exception t)
                {
                    _errorHandler(t);
                }

                _subscriberPosition.SetOrdered(position + bytesConsumed);
            }

            return(bytesConsumed);
        }
        public void ShouldScanEmptyBuffer()
        {
            const int offset = 0;
            int limit = _termBuffer.Capacity;

            int newOffset = TermBlockScanner.Scan(_termBuffer, offset, limit);
            Assert.AreEqual(offset, newOffset);
        }
Exemple #5
0
        public void ShouldReadFirstMessage()
        {
            const int offset               = 0;
            int       limit                = _termBuffer.Capacity;
            const int messageLength        = 50;
            int       alignedMessageLength = BitUtil.Align(messageLength, FrameDescriptor.FRAME_ALIGNMENT);

            A.CallTo(() => _termBuffer.GetIntVolatile(FrameDescriptor.LengthOffset(offset)))
            .Returns(messageLength);

            int newOffset = TermBlockScanner.Scan(_termBuffer, offset, limit);

            Assert.That(newOffset, Is.EqualTo(alignedMessageLength));
        }
        public void ShouldReadOneMessageOnLimit()
        {
            const int offset = 0;
            const int messageLength = 50;
            int alignedMessageLength = BitUtil.Align(messageLength, FrameDescriptor.FRAME_ALIGNMENT);
            int limit = alignedMessageLength;

            A.CallTo(() => _termBuffer.GetIntVolatile(FrameDescriptor.LengthOffset(offset)))
                .Returns(messageLength);

            int newOffset = TermBlockScanner.Scan(_termBuffer, offset, limit);

            Assert.AreEqual(alignedMessageLength, newOffset);
        }
        public void ShouldReadFirstMessage()
        {
            const int offset = 0;
            int limit = _termBuffer.Capacity;
            const int messageLength = 50;
            int alignedMessageLength = BitUtil.Align(messageLength, FrameDescriptor.FRAME_ALIGNMENT);

            A.CallTo(() => _termBuffer.GetIntVolatile(FrameDescriptor.LengthOffset(offset)))
                .Returns(messageLength);
            A.CallTo(() => _termBuffer.GetShort(FrameDescriptor.TypeOffset(offset)))
                .Returns((short)HeaderFlyweight.HDR_TYPE_DATA);

            int newOffset = TermBlockScanner.Scan(_termBuffer, offset, limit);
            Assert.AreEqual(alignedMessageLength, newOffset);
        }
Exemple #8
0
        public void ShouldReadBlockOfOneMessageThenPadding()
        {
            const int offset               = 0;
            int       limit                = _termBuffer.Capacity;
            int       messageLength        = 50;
            int       alignedMessageLength = BitUtil.Align(messageLength, FrameDescriptor.FRAME_ALIGNMENT);

            A.CallTo(() => _termBuffer.GetIntVolatile(FrameDescriptor.LengthOffset(offset))).Returns(messageLength);
            A.CallTo(() => _termBuffer.GetShort(FrameDescriptor.TypeOffset(offset))).Returns((short)HeaderFlyweight.HDR_TYPE_DATA);
            A.CallTo(() => _termBuffer.GetIntVolatile(FrameDescriptor.LengthOffset(alignedMessageLength))).Returns(messageLength);
            A.CallTo(() => _termBuffer.GetShort(FrameDescriptor.TypeOffset(alignedMessageLength))).Returns((short)HeaderFlyweight.HDR_TYPE_PAD);

            int firstOffset = TermBlockScanner.Scan(_termBuffer, offset, limit);

            Assert.That(firstOffset, Is.EqualTo(alignedMessageLength));

            int secondOffset = TermBlockScanner.Scan(_termBuffer, firstOffset, limit);

            Assert.That(secondOffset, Is.EqualTo(alignedMessageLength * 2));
        }