예제 #1
0
        public void ShouldPassThroughUnfragmentedMessage()
        {
            A.CallTo(() => header.Flags).Returns(FrameDescriptor.UNFRAGMENTED);

            var       srcBuffer = new UnsafeBuffer(new byte[128]);
            const int offset    = 8;
            const int length    = 32;

            adapter.OnFragment(srcBuffer, offset, length, header);

            A.CallTo(() => delegateFragmentHandler.OnFragment(srcBuffer, offset, length, header))
            .MustHaveHappened(Repeated.Exactly.Once);
        }
예제 #2
0
        /// <summary>
        /// The implementation of <seealso cref="FragmentHandler"/> that reassembles and forwards whole messages.
        /// </summary>
        /// <param name="buffer"> containing the data. </param>
        /// <param name="offset"> at which the data begins. </param>
        /// <param name="length"> of the data in bytes. </param>
        /// <param name="header"> representing the meta data for the data. </param>
        public void OnFragment(IDirectBuffer buffer, int offset, int length, Header header)
        {
            byte flags = header.Flags;

            if ((flags & FrameDescriptor.UNFRAGMENTED) == FrameDescriptor.UNFRAGMENTED)
            {
                _delegate.OnFragment(buffer, offset, length, header);
            }
            else
            {
                HandleFragment(buffer, offset, length, header, flags);
            }
        }
예제 #3
0
        public static long Read(UnsafeBuffer termBuffer, int offset, IFragmentHandler handler, int fragmentsLimit, Header header, ErrorHandler errorHandler)
        {
            int fragmentsRead = 0;
            int capacity      = termBuffer.Capacity;

            try
            {
                do
                {
                    int frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, offset);
                    if (frameLength <= 0)
                    {
                        break;
                    }

                    int termOffset = offset;
                    offset += BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);

                    if (!FrameDescriptor.IsPaddingFrame(termBuffer, termOffset))
                    {
                        header.SetBuffer(termBuffer, termOffset);

                        handler.OnFragment(termBuffer, termOffset + DataHeaderFlyweight.HEADER_LENGTH, frameLength - DataHeaderFlyweight.HEADER_LENGTH, header);

                        ++fragmentsRead;
                    }
                } while (fragmentsRead < fragmentsLimit && offset < capacity);
            }
            catch (Exception t)
            {
                errorHandler(t);
            }

            return(Pack(offset, fragmentsRead));
        }
예제 #4
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="FragmentHandler"/> up to a limited number of fragments as specified or
        /// the maximum position specified.
        /// <para>
        /// Use a <seealso cref="FragmentAssembler"/> to assemble messages which span multiple fragments.
        ///
        /// </para>
        /// </summary>
        /// <param name="handler">       to which message fragments are delivered. </param>
        /// <param name="limitPosition"> to consume messages up to. </param>
        /// <param name="fragmentLimit"> for the number of fragments to be consumed during one polling operation. </param>
        /// <returns> the number of fragments that have been consumed. </returns>
        /// <seealso cref="FragmentAssembler" />
        /// <seealso cref="ImageFragmentAssembler" />
        public int BoundedPoll(IFragmentHandler handler, long limitPosition, int fragmentLimit)
        {
            if (_isClosed)
            {
                return(0);
            }

            int          fragmentsRead   = 0;
            long         initialPosition = _subscriberPosition.Get();
            int          initialOffset   = (int)initialPosition & _termLengthMask;
            int          offset          = initialOffset;
            UnsafeBuffer termBuffer      = ActiveTermBuffer(initialPosition);
            int          limitOffset     = (int)Math.Min(termBuffer.Capacity, (limitPosition - initialPosition) + offset);
            Header       header          = _header;

            header.Buffer = termBuffer;

            try
            {
                while (fragmentsRead < fragmentLimit && offset < limitOffset)
                {
                    int length = FrameDescriptor.FrameLengthVolatile(termBuffer, offset);
                    if (length <= 0)
                    {
                        break;
                    }

                    int frameOffset   = offset;
                    int alignedLength = BitUtil.Align(length, FrameDescriptor.FRAME_ALIGNMENT);
                    offset += alignedLength;

                    if (FrameDescriptor.IsPaddingFrame(termBuffer, frameOffset))
                    {
                        continue;
                    }

                    header.Offset = frameOffset;
                    handler.OnFragment(termBuffer, frameOffset + DataHeaderFlyweight.HEADER_LENGTH, length - DataHeaderFlyweight.HEADER_LENGTH, header);
                    ++fragmentsRead;
                }
            }
            catch (Exception t)
            {
                _errorHandler(t);
            }
            finally
            {
                long resultingPosition = initialPosition + (offset - initialOffset);
                if (resultingPosition > initialPosition)
                {
                    _subscriberPosition.SetOrdered(resultingPosition);
                }
            }

            return(fragmentsRead);
        }
예제 #5
0
        public static int Read(
            UnsafeBuffer termBuffer,
            int termOffset,
            IFragmentHandler handler,
            int fragmentsLimit,
            Header header,
            ErrorHandler errorHandler,
            long currentPosition,
            IPosition subscriberPosition)
        {
            int fragmentsRead = 0;
            int offset        = termOffset;
            int capacity      = termBuffer.Capacity;

            header.Buffer = termBuffer;

            try
            {
                while (fragmentsRead < fragmentsLimit && offset < capacity)
                {
                    int frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, offset);
                    if (frameLength <= 0)
                    {
                        break;
                    }

                    int frameOffset = offset;
                    offset += BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);

                    if (!FrameDescriptor.IsPaddingFrame(termBuffer, frameOffset))
                    {
                        header.Offset = frameOffset;
                        handler.OnFragment(termBuffer, frameOffset + DataHeaderFlyweight.HEADER_LENGTH, frameLength - DataHeaderFlyweight.HEADER_LENGTH, header);

                        ++fragmentsRead;
                    }
                }
            }

            catch (Exception t)
            {
                errorHandler(t);
            }
            finally
            {
                long newPosition = currentPosition + (offset - termOffset);
                if (newPosition > currentPosition)
                {
                    subscriberPosition.SetOrdered(newPosition);
                }
            }

            return(fragmentsRead);
        }
예제 #6
0
        public void ShouldReadData()
        {
            Subscription.AddImage(ImageOneMock);

            A.CallTo(() => ImageOneMock.Poll(A <IFragmentHandler> ._, A <int> ._)).ReturnsLazily(o =>
            {
                var handler = (IFragmentHandler)o.Arguments[0];
                handler.OnFragment(AtomicReadBuffer, HEADER_LENGTH, READ_BUFFER_CAPACITY - HEADER_LENGTH, Header);
                return(1);
            });

            Assert.AreEqual(1, Subscription.Poll(FragmentHandler, FRAGMENT_COUNT_LIMIT));

            A.CallTo(() => FragmentHandler.OnFragment(AtomicReadBuffer, HEADER_LENGTH, READ_BUFFER_CAPACITY - HEADER_LENGTH, A <Header> ._)).MustHaveHappened();
        }
예제 #7
0
        public void ShouldReportCorrectPositionOnReception()
        {
            var initialPosition =
                LogBufferDescriptor.ComputePosition(INITIAL_TERM_ID, 0, POSITION_BITS_TO_SHIFT, INITIAL_TERM_ID);

            Position.SetOrdered(initialPosition);
            var image = CreateImage();

            InsertDataFrame(INITIAL_TERM_ID, OffsetForFrame(0));

            var messages = image.Poll(MockFragmentHandler, int.MaxValue);

            Assert.AreEqual(1, messages);

            A.CallTo(() =>
                     MockFragmentHandler.OnFragment(A <UnsafeBuffer> ._, DataHeaderFlyweight.HEADER_LENGTH, DATA.Length,
                                                    A <Header> ._)).MustHaveHappened();

            A.CallTo(() => Position.SetOrdered(initialPosition)).MustHaveHappened().Then(
                A.CallTo(() => Position.SetOrdered(initialPosition + ALIGNED_FRAME_LENGTH)).MustHaveHappened()
                );
        }
예제 #8
0
        public void ShouldReadFirstMessage()
        {
            const int msgLength          = 1;
            int       frameLength        = HEADER_LENGTH + msgLength;
            int       alignedFrameLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            const int termOffset         = 0;

            A.CallTo(() => termBuffer.GetIntVolatile(0))
            .Returns(frameLength);
            A.CallTo(() => termBuffer.GetShort(FrameDescriptor.TypeOffset(0)))
            .Returns((short)HeaderFlyweight.HDR_TYPE_DATA);

            int readOutcome = TermReader.Read(termBuffer, termOffset, handler, int.MaxValue, header, errorHandler, 0, subscriberPosition);

            Assert.That(TermReader.FragmentsRead(readOutcome), Is.EqualTo(1));

            A.CallTo(() => termBuffer.GetIntVolatile(0)).MustHaveHappened()
            .Then(A.CallTo(() => handler.OnFragment(termBuffer, HEADER_LENGTH, msgLength, A <Header> ._)).MustHaveHappened())
            .Then(A.CallTo(() => subscriberPosition.SetOrdered(alignedFrameLength)).MustHaveHappened());
        }