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);
        }
Exemple #4
0
        /**
         * Poll for new messages in a stream. If new messages are found beyond the last consumed position then they
         * will be delivered to the {@link FileBlockHandler} up to a limited number of bytes.
         *
         * @param fileBlockHandler to which block is delivered.
         * @param blockLengthLimit up to which a block may be in length.
         * @return the number of bytes that have been consumed.
         */
        public int filePoll(FileBlockHandler fileBlockHandler, int blockLengthLimit)
        {
            if (isClosed)
            {
                return(0);
            }

            long         position    = subscriberPosition.get();
            int          termOffset  = (int)position & termLengthMask;
            int          activeIndex = indexByPosition(position, positionBitsToShift);
            DirectBuffer termBuffer  = termBuffers[activeIndex];
            int          capacity    = termBuffer.capacity();
            int          limit       = Math.min(termOffset + blockLengthLimit, capacity);

            int resultingOffset = TermBlockScanner.scan(termBuffer, termOffset, limit);

            int bytesConsumed = resultingOffset - termOffset;

            if (resultingOffset > termOffset)
            {
                try {
                    long offset = ((long)capacity * activeIndex) + termOffset;
                    int  termId = termBuffer.getInt(termOffset + TERM_ID_FIELD_OFFSET, LITTLE_ENDIAN);

                    fileBlockHandler.onBlock(logBuffers.fileChannel(), offset, bytesConsumed, sessionId, termId);
                } catch (Throwable t) {
                    errorHandler.onError(t);
                }

                subscriberPosition.setOrdered(position + bytesConsumed);
            }

            return(bytesConsumed);
        }
Exemple #5
0
        /**
         * Poll for new messages in a stream. If new messages are found beyond the last consumed position then they
         * will be delivered to the {@link BlockHandler} up to a limited number of bytes.
         *
         * @param blockHandler     to which block is delivered.
         * @param blockLengthLimit up to which a block may be in length.
         * @return the number of bytes that have been consumed.
         */
        public int blockPoll(BlockHandler blockHandler, int blockLengthLimit)
        {
            if (isClosed)
            {
                return(0);
            }

            long         position   = subscriberPosition.get();
            int          termOffset = (int)position & termLengthMask;
            DirectBuffer termBuffer = activeTermBuffer(position);
            int          limit      = Math.min(termOffset + blockLengthLimit, termBuffer.capacity());

            int resultingOffset = TermBlockScanner.scan(termBuffer, termOffset, limit);

            int bytesConsumed = resultingOffset - termOffset;

            if (resultingOffset > termOffset)
            {
                try {
                    int termId = termBuffer.getInt(termOffset + TERM_ID_FIELD_OFFSET, LITTLE_ENDIAN);

                    blockHandler.onBlock(termBuffer, termOffset, bytesConsumed, sessionId, termId);
                } catch (Throwable t) {
                    errorHandler.onError(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 #7
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 #10
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));
        }