예제 #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="IControlledFragmentHandler"/> up to a limited number of fragments as specified or
        /// the maximum position specified.
        /// <para>
        /// Use a <seealso cref="IControlledFragmentHandler"/> 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="ControlledFragmentAssembler"/>
        /// <seealso cref="ImageControlledFragmentAssembler"/>
        public int BoundedControlledPoll(ControlledFragmentHandler handler, long limitPosition,
                                         int fragmentLimit)
        {
            var fragmentHandler = HandlerHelper.ToControlledFragmentHandler(handler);

            return(BoundedControlledPoll(fragmentHandler, limitPosition, fragmentLimit));
        }
예제 #2
0
        public void SetUp()
        {
            RcvBuffer                     = new UnsafeBuffer(new byte[ALIGNED_FRAME_LENGTH]);
            DataHeader                    = new DataHeaderFlyweight();
            MockFragmentHandler           = A.Fake <FragmentHandler>();
            MockControlledFragmentHandler = A.Fake <ControlledFragmentHandler>();
            Position     = A.Fake <IPosition>(options => options.Wrapping(new AtomicLongPosition()));
            LogBuffers   = A.Fake <LogBuffers>();
            ErrorHandler = A.Fake <ErrorHandler>();
            Subscription = A.Fake <Subscription>();

            TermBuffers = new UnsafeBuffer[LogBufferDescriptor.PARTITION_COUNT];

            DataHeader.Wrap(RcvBuffer);

            for (var i = 0; i < LogBufferDescriptor.PARTITION_COUNT; i++)
            {
                TermBuffers[i] = new UnsafeBuffer(new byte[TERM_BUFFER_LENGTH]);
            }

            var logMetaDataBuffer = new UnsafeBuffer(new byte[LogBufferDescriptor.LOG_META_DATA_LENGTH]);

            A.CallTo(() => LogBuffers.TermBuffers()).Returns(TermBuffers);
            A.CallTo(() => LogBuffers.TermLength()).Returns(TERM_BUFFER_LENGTH);
            A.CallTo(() => LogBuffers.MetaDataBuffer()).Returns(logMetaDataBuffer);
        }
예제 #3
0
        /// <summary>
        /// Poll in a controlled manner the <seealso cref="Image"/>s under the subscription for available message fragments.
        /// Control is applied to fragments in the stream. If more fragments can be read on another stream
        /// they will even if BREAK or ABORT is returned from the fragment handler.
        /// <para>
        /// Each fragment read will be a whole message if it is under MTU length. If larger than MTU then it will come
        /// as a series of fragments ordered within a session.
        /// </para>
        /// <para>
        /// To assemble messages that span multiple fragments then use <seealso cref="ControlledFragmentAssembler"/>.
        ///
        /// </para>
        /// </summary>
        /// <param name="fragmentHandler"> callback for handling each message fragment as it is read. </param>
        /// <param name="fragmentLimit">   number of message fragments to limit for the poll operation across multiple <seealso cref="Image"/>s. </param>
        /// <returns> the number of fragments received </returns>
        /// <seealso cref="ControlledFragmentHandler" />
        public int ControlledPoll(ControlledFragmentHandler fragmentHandler, int fragmentLimit)
        {
            var images        = _fields.images;
            var length        = images.Length;
            var fragmentsRead = 0;

            var startingIndex = _fields.roundRobinIndex++;

            if (startingIndex >= length)
            {
                _fields.roundRobinIndex = startingIndex = 0;
            }

            for (var i = startingIndex; i < length && fragmentsRead < fragmentLimit; i++)
            {
                fragmentsRead += images[i].ControlledPoll(fragmentHandler, fragmentLimit - fragmentsRead);
            }

            for (var i = 0; i < startingIndex && fragmentsRead < fragmentLimit; i++)
            {
                fragmentsRead += images[i].ControlledPoll(fragmentHandler, fragmentLimit - fragmentsRead);
            }

            return(fragmentsRead);
        }
예제 #4
0
파일: Image.cs 프로젝트: megakid/Aeron.NET
        /// <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="IControlledFragmentHandler"/> up to a limited number of fragments as specified or
        /// the maximum position specified.
        /// <para>
        /// Use a <seealso cref="IControlledFragmentHandler"/> to assemble messages which span multiple fragments.
        ///
        /// </para>
        /// </summary>
        /// <param name="fragmentHandler"> to which message fragments are delivered. </param>
        /// <param name="maxPosition">     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="ControlledFragmentAssembler"/>
        /// <seealso cref="ImageControlledFragmentAssembler"/>
        public virtual int BoundedControlledPoll(ControlledFragmentHandler fragmentHandler, long maxPosition,
                                                 int fragmentLimit)
        {
            var handler = HandlerHelper.ToControlledFragmentHandler(fragmentHandler);

            return(BoundedControlledPoll(handler, maxPosition, fragmentLimit));
        }
예제 #5
0
        public long ControlledPeek(long initialPosition, ControlledFragmentHandler handler, long limitPosition)
        {
            var fragmentHandler = HandlerHelper.ToControlledFragmentHandler(handler);

            return(ControlledPeek(initialPosition, fragmentHandler, limitPosition));
        }
예제 #6
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="ControlledFragmentHandler"/> up to a limited number of fragments as specified.
        ///
        /// Use a <see cref="ControlledFragmentAssembler"/>. to assemble messages which span multiple fragments.
        ///
        /// </summary>
        /// <param name="handler"> to which message fragments are delivered. </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="ControlledFragmentAssembler" />
        /// <seealso cref="ImageControlledFragmentAssembler" />
        public int ControlledPoll(ControlledFragmentHandler handler, int fragmentLimit)
        {
            var fragmentHandler = HandlerHelper.ToControlledFragmentHandler(handler);

            return(ControlledPoll(fragmentHandler, fragmentLimit));
        }
예제 #7
0
        /// <summary>
        /// Peek for new messages in a stream by scanning forward from an initial position. If new messages are found then
        /// they will be delivered to the <seealso cref="IControlledFragmentHandler"/> up to a limited position.
        ///
        /// Use a <seealso cref="ControlledFragmentAssembler"/> to assemble messages which span multiple fragments. Scans must also
        /// start at the beginning of a message so that the assembler is reset.
        ///
        /// </summary>
        /// <param name="initialPosition"> from which to peek forward. </param>
        /// <param name="fragmentHandler"> to which message fragments are delivered. </param>
        /// <param name="limitPosition">   up to which can be scanned. </param>
        /// <returns> the resulting position after the scan terminates which is a complete message. </returns>
        /// <seealso cref="ControlledFragmentAssembler"/>
        /// <seealso cref="ImageControlledFragmentAssembler"/>
        public virtual long ControlledPeek(long initialPosition, ControlledFragmentHandler fragmentHandler, long limitPosition)
        {
            if (_isClosed)
            {
                return(0);
            }

            ValidatePosition(initialPosition);

            int          initialOffset = (int)initialPosition & _termLengthMask;
            int          offset        = initialOffset;
            long         position      = initialPosition;
            UnsafeBuffer termBuffer    = ActiveTermBuffer(initialPosition);
            int          capacity      = termBuffer.Capacity;

            _header.Buffer = termBuffer;
            long resultingPosition = initialPosition;

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

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

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

                    _header.Offset = frameOffset;


                    var action = fragmentHandler(
                        termBuffer,
                        frameOffset + DataHeaderFlyweight.HEADER_LENGTH,
                        length - DataHeaderFlyweight.HEADER_LENGTH,
                        _header);

                    if (action == ControlledFragmentHandlerAction.ABORT)
                    {
                        break;
                    }

                    position     += (offset - initialOffset);
                    initialOffset = offset;

                    if ((_header.Flags & FrameDescriptor.END_FRAG_FLAG) == FrameDescriptor.END_FRAG_FLAG)
                    {
                        resultingPosition = position;
                    }

                    if (action == ControlledFragmentHandlerAction.BREAK)
                    {
                        break;
                    }
                } while (position < limitPosition && offset < capacity);
            }
            catch (Exception t)
            {
                _errorHandler(t);
            }

            return(resultingPosition);
        }
예제 #8
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="IControlledFragmentHandler"/> up to a limited number of fragments as specified.
        ///
        /// Use a <see cref="ControlledFragmentAssembler"/>. to assemble messages which span multiple fragments.
        ///
        /// </summary>
        /// <param name="fragmentHandler"> to which message fragments are delivered. </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="ControlledFragmentAssembler" />
        /// <seealso cref="ImageControlledFragmentAssembler" />
        public int ControlledPoll(ControlledFragmentHandler fragmentHandler, int fragmentLimit)
        {
            if (_isClosed)
            {
                return(0);
            }

            var fragmentsRead   = 0;
            var initialPosition = _subscriberPosition.Get();
            var initialOffset   = (int)initialPosition & _termLengthMask;
            var resultingOffset = initialOffset;
            var termBuffer      = ActiveTermBuffer(initialPosition);
            int capacity        = termBuffer.Capacity;

            _header.Buffer = termBuffer;

            try
            {
                do
                {
                    var length = FrameDescriptor.FrameLengthVolatile(termBuffer, resultingOffset);
                    if (length <= 0)
                    {
                        break;
                    }

                    var frameOffset   = resultingOffset;
                    var alignedLength = BitUtil.Align(length, FrameDescriptor.FRAME_ALIGNMENT);
                    resultingOffset += alignedLength;

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

                    var action = fragmentHandler(
                        termBuffer,
                        frameOffset + DataHeaderFlyweight.HEADER_LENGTH,
                        length - DataHeaderFlyweight.HEADER_LENGTH,
                        _header);

                    if (action == ControlledFragmentHandlerAction.ABORT)
                    {
                        resultingOffset -= alignedLength;
                        break;
                    }

                    ++fragmentsRead;

                    if (action == ControlledFragmentHandlerAction.BREAK)
                    {
                        break;
                    }
                    else if (action == ControlledFragmentHandlerAction.COMMIT)
                    {
                        initialPosition += (resultingOffset - initialOffset);
                        initialOffset    = resultingOffset;
                        _subscriberPosition.SetOrdered(initialPosition);
                    }
                } while (fragmentsRead < fragmentLimit && resultingOffset < capacity);
            }
            catch (Exception t)
            {
                _errorHandler(t);
            }
            finally
            {
                long resultingPosition = initialPosition + (resultingOffset - initialOffset);
                if (resultingPosition > initialPosition)
                {
                    _subscriberPosition.SetOrdered(resultingPosition);
                }
            }

            return(fragmentsRead);
        }
예제 #9
0
 public static IControlledFragmentHandler ToControlledFragmentHandler(ControlledFragmentHandler @delegate)
 {
     return(new ControlledFragmentHandlerWrapper(@delegate));
 }
예제 #10
0
 public ControlledFragmentHandlerWrapper(ControlledFragmentHandler @delegate)
 {
     _delegate = @delegate;
 }
 /// <summary>
 /// Construct an adapter to reassembly message fragments and delegate on only whole messages.
 /// </summary>
 /// <param name="delegate">            onto which whole messages are forwarded. </param>
 /// <param name="initialBufferLength"> to be used for each session. </param>
 public ImageControlledFragmentAssembler(ControlledFragmentHandler @delegate, int initialBufferLength = BufferBuilder.MIN_ALLOCATED_CAPACITY)
 {
     _delegate = @delegate;
     _builder  = new BufferBuilder(initialBufferLength);
 }
예제 #12
0
파일: Image.cs 프로젝트: s952163/Spreads
        /**
         * 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 ControlledFragmentHandler} up to a limited number of fragments as specified.
         *
         * To assemble messages that span multiple fragments then use {@link ControlledFragmentAssembler}.
         *
         * @param fragmentHandler to which message fragments are delivered.
         * @param fragmentLimit   for the number of fragments to be consumed during one polling operation.
         * @return the number of fragments that have been consumed.
         * @see ControlledFragmentAssembler
         */
        public int controlledPoll(ControlledFragmentHandler fragmentHandler, int fragmentLimit)
        {
            if (isClosed)
            {
                return(0);
            }

            long         position      = subscriberPosition.get();
            int          termOffset    = (int)position & termLengthMask;
            int          offset        = termOffset;
            int          fragmentsRead = 0;
            DirectBuffer termBuffer    = activeTermBuffer(position);

            try {
                int capacity = termBuffer.capacity();
                do
                {
                    int length = frameLengthVolatile(termBuffer, offset);
                    if (length <= 0)
                    {
                        break;
                    }

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

                    if (!isPaddingFrame(termBuffer, frameOffset))
                    {
                        header.buffer(termBuffer);
                        header.offset(frameOffset);

                        Action action = fragmentHandler.onFragment(
                            termBuffer, frameOffset + HEADER_LENGTH, length - HEADER_LENGTH, header);

                        ++fragmentsRead;

                        if (action == BREAK)
                        {
                            break;
                        }
                        else if (action == ABORT)
                        {
                            --fragmentsRead;
                            offset = frameOffset;
                            break;
                        }
                        else if (action == COMMIT)
                        {
                            position  += alignedLength;
                            termOffset = offset;
                            subscriberPosition.setOrdered(position);
                        }
                    }
                }while (fragmentsRead < fragmentLimit && offset < capacity);
            } catch (Throwable t) {
                errorHandler.onError(t);
            }

            updatePosition(position, termOffset, offset);

            return(fragmentsRead);
        }
 /// <summary>
 /// Construct an adapter to reassembly message fragments and delegate on only whole messages.
 /// </summary>
 /// <param name="delegate">            onto which whole messages are forwarded. </param>
 /// <param name="initialBufferLength"> to be used for each session. </param>
 public ControlledFragmentAssembler(ControlledFragmentHandler @delegate, int initialBufferLength = BufferBuilder.MIN_ALLOCATED_CAPACITY)
 {
     _initialBufferLength = initialBufferLength;
     _delegate            = @delegate;
 }