public void SetUp() { RcvBuffer = new UnsafeBuffer(new byte[ALIGNED_FRAME_LENGTH]); DataHeader = new DataHeaderFlyweight(); MockFragmentHandler = A.Fake <IFragmentHandler>(); MockControlledFragmentHandler = A.Fake <IControlledFragmentHandler>(); 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.DuplicateTermBuffers()).Returns(TermBuffers); A.CallTo(() => LogBuffers.TermLength()).Returns(TERM_BUFFER_LENGTH); A.CallTo(() => LogBuffers.MetaDataBuffer()).Returns(logMetaDataBuffer); }
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)); }
public void Setup() { ImageOneMock = A.Fake <Image>(); ImageTwoMock = A.Fake <Image>(); A.CallTo(() => ImageOneMock.CorrelationId).Returns(1); A.CallTo(() => ImageTwoMock.CorrelationId).Returns(2); AtomicReadBuffer = new UnsafeBuffer(new byte[READ_BUFFER_CAPACITY]); Conductor = A.Fake <ClientConductor>(); FragmentHandler = A.Fake <IFragmentHandler>(); Header = A.Fake <Header>(); AvailableImageHandler = A.Fake <AvailableImageHandler>(); UnavailableImageHandler = A.Fake <UnavailableImageHandler>(); A.CallTo(() => Header.Flags).Returns(FLAGS); Subscription = new Subscription( Conductor, CHANNEL, STREAM_ID_1, SUBSCRIPTION_CORRELATION_ID, AvailableImageHandler, UnavailableImageHandler); A.CallTo(() => Conductor.ReleaseSubscription(Subscription)).Invokes(() => Subscription.InternalClose()); }
/// <summary> /// Poll the <seealso cref="Image"/>s under the subscription for available message fragments. /// <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="FragmentAssembler"/>. /// /// </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> public int Poll(IFragmentHandler 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].Poll(fragmentHandler, fragmentLimit - fragmentsRead); } for (var i = 0; i < startingIndex && fragmentsRead < fragmentLimit; i++) { fragmentsRead += images[i].Poll(fragmentHandler, fragmentLimit - fragmentsRead); } return(fragmentsRead); }
/// <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); }
public void SetUp() { header = new Header(INITIAL_TERM_ID, TERM_BUFFER_CAPACITY); termBuffer = A.Fake <UnsafeBuffer>(); errorHandler = A.Fake <ErrorHandler>(); handler = A.Fake <IFragmentHandler>(); subscriberPosition = A.Fake <IPosition>(); A.CallTo(() => termBuffer.Capacity).Returns(TERM_BUFFER_CAPACITY); }
/// <summary> /// Return a reusable, parameterized event loop that calls and idler when no messages are received /// </summary> /// <param name="fragmentHandler"> to be called back for each message. </param> /// <param name="limit"> passed to <seealso cref="Subscription#poll(FragmentHandler, int)"/> </param> /// <param name="running"> indication for loop </param> /// <param name="idleStrategy"> to use for loop </param> /// <returns> loop function </returns> public static Action <Subscription> SubscriberLoop(IFragmentHandler fragmentHandler, int limit, AtomicBoolean running, IIdleStrategy idleStrategy) { return(subscription => { while (running) { idleStrategy.Idle(subscription.Poll(fragmentHandler, limit)); } }); }
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); }
public void SetUp() { delegateFragmentHandler = A.Fake <IFragmentHandler>(); termBuffer = A.Fake <IDirectBuffer>(); adapter = new FragmentAssembler(delegateFragmentHandler); header = A.Fake <Header>(x => x.Wrapping(new Header(INITIAL_TERM_ID, LogBufferDescriptor.TERM_MIN_LENGTH))); header.SetBuffer(termBuffer, 0); A.CallTo(() => termBuffer.GetInt(A <int> ._)).Returns(SESSION_ID); }
private static void RoundTripMessages(UnsafeBuffer buffer, IFragmentHandler fragmentHandler, Publication publication, Subscription subscription, int count) { for (var i = 0; i < count; i++) { do { buffer.PutLong(0, Stopwatch.GetTimestamp()); } while (publication.Offer(buffer, 0, MessageLength) < 0L); PollingIdleStrategy.Reset(); while (subscription.Poll(fragmentHandler, FragmentCountLimit) <= 0) { PollingIdleStrategy.Idle(); } } }
/// <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. /// /// Use a <see cref="FragmentAssembler"/> 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="FragmentAssembler" /> /// <seealso cref="ImageFragmentAssembler" /> public int Poll(IFragmentHandler fragmentHandler, int fragmentLimit) { if (_isClosed) { return(0); } var position = _subscriberPosition.Get(); return(TermReader.Read( ActiveTermBuffer(position), (int)position & _termLengthMask, fragmentHandler, fragmentLimit, _header, _errorHandler, position, _subscriberPosition)); }
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public FragmentAssembler(FragmentHandler fragmentHandler, int initialBufferLength = 0) { _initialBufferLength = initialBufferLength; _delegate = HandlerHelper.ToFragmentHandler(fragmentHandler); }
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public ImageFragmentAssembler(FragmentHandler fragmentHandler, int initialBufferLength = BufferBuilder.MIN_ALLOCATED_CAPACITY) { _delegate = HandlerHelper.ToFragmentHandler(fragmentHandler); _builder = new BufferBuilder(initialBufferLength); }
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public ImageFragmentAssembler(IFragmentHandler fragmentHandler, int initialBufferLength = 0) { _delegate = fragmentHandler; _builder = new BufferBuilder(initialBufferLength); }
/// <summary> /// Return a reusable, parameterised event loop that calls a default idler when no messages are received /// </summary> /// <param name="fragmentHandler"> to be called back for each message. </param> /// <param name="limit"> passed to <seealso cref="Subscription#poll(FragmentHandler, int)"/> </param> /// <param name="running"> indication for loop </param> /// <returns> loop function </returns> public static Action <Subscription> SubscriberLoop(IFragmentHandler fragmentHandler, int limit, AtomicBoolean running) { IIdleStrategy idleStrategy = new BusySpinIdleStrategy(); return(SubscriberLoop(fragmentHandler, limit, running, idleStrategy)); }
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public FragmentAssembler(IFragmentHandler fragmentHandler, int initialBufferLength = 0) { _initialBufferLength = initialBufferLength; _delegate = fragmentHandler; }
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public ImageFragmentAssembler(FragmentHandler fragmentHandler, int initialBufferLength = 0) { _delegate = HandlerHelper.ToFragmentHandler(fragmentHandler); _builder = new BufferBuilder(initialBufferLength); }
/// <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. /// /// Use a <see cref="FragmentAssembler"/> 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="FragmentAssembler" /> /// <seealso cref="ImageFragmentAssembler" /> #if DEBUG public virtual int Poll(IFragmentHandler fragmentHandler, int fragmentLimit)
/// <summary> /// Construct an adapter to reassemble message fragments and _delegate on only whole messages. /// </summary> /// <param name="fragmentHandler"> onto which whole messages are forwarded. </param> /// <param name="initialBufferLength"> to be used for each session. </param> public FragmentAssembler(FragmentHandler fragmentHandler, int initialBufferLength = BufferBuilder.MIN_ALLOCATED_CAPACITY) { _initialBufferLength = initialBufferLength; _delegate = HandlerHelper.ToFragmentHandler(fragmentHandler); }