public OneToThreeSequencedThroughputTest() : base(Test_Disruptor, ITERATIONS, 7) { ThreadPool.SetMaxThreads(NUM_EVENT_PROCESSORS, NUM_EVENT_PROCESSORS); for (long i = 0; i < ITERATIONS; i++) { results[0] = Operation.Addition.Op(results[0], i); results[1] = Operation.Substraction.Op(results[1], i); results[2] = Operation.And.Op(results[2], i); } sequenceBarrier = ringBuffer.NewBarrier(); handlers[0] = new ValueMutationEventHandler_v3(Operation.Addition); handlers[1] = new ValueMutationEventHandler_v3(Operation.Substraction); handlers[2] = new ValueMutationEventHandler_v3(Operation.And); batchEventProcessors[0] = new BatchEventProcessor <ValueEvent>(ringBuffer, sequenceBarrier, handlers[0]); batchEventProcessors[1] = new BatchEventProcessor <ValueEvent>(ringBuffer, sequenceBarrier, handlers[1]); batchEventProcessors[2] = new BatchEventProcessor <ValueEvent>(ringBuffer, sequenceBarrier, handlers[2]); ringBuffer.AddGatingSequences( batchEventProcessors[0].Sequence, batchEventProcessors[1].Sequence, batchEventProcessors[2].Sequence); }
/// <summary> /// <see cref="IWaitStrategy.WaitFor"/> /// </summary> public long WaitFor(long sequence, Sequence cursor, ISequence dependentSequence, ISequenceBarrier barrier) { long startTime = 0; int counter = _spinTries; do { long availableSequence; if ((availableSequence = dependentSequence.Value) >= sequence) return availableSequence; if (0 == --counter) { if (0 == startTime) { startTime = GetSystemTimeTicks(); } else { var timeDelta = GetSystemTimeTicks() - startTime; if (timeDelta > _yieldTimeoutTicks) { return _fallbackStrategy.WaitFor(sequence, cursor, dependentSequence, barrier); } if (timeDelta > _spinTimeoutTicks) { Thread.Yield(); } } counter = _spinTries; } } while (true); }
/// <summary> /// <see cref="IWaitStrategy.WaitFor"/> /// </summary> public long WaitFor(long sequence, Sequence cursor, ISequence dependentSequence, ISequenceBarrier barrier) { var timeSpan = _timeout; if (cursor.Value < sequence) { lock (_gate) { while (cursor.Value < sequence) { barrier.CheckAlert(); if (!Monitor.Wait(_gate, timeSpan)) { throw TimeoutException.Instance; } } } } long availableSequence; while ((availableSequence = dependentSequence.Value) < sequence) { barrier.CheckAlert(); } return availableSequence; }
/// <summary> /// Wait for the given sequence to be available /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">Ring buffer cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier) { var availableSequence = cursor.Value; // volatile read if (availableSequence < sequence) { Monitor.Enter(_gate); try { while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); Monitor.Wait(_gate); } } finally { Monitor.Exit(_gate); } } if (dependents.Length != 0) { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); } } return availableSequence; }
/// <summary> /// Wait for the given sequence to be available /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">Ring buffer cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier) { long availableSequence; var spinWait = default(SpinWait); if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); spinWait.SpinOnce(); if (spinWait.Count > 5000) break; } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); spinWait.SpinOnce(); if (spinWait.Count > 5000) break; } } return availableSequence; }
public Lite_Timeout_Blocking_Wait_Strategy_Test() { _barrier = new DummySequenceBarrier(); _strategy = new LiteTimeoutBlockingWaitStrategy(TimeoutMilliseconds); _cursor = new Sequence(5); _dependent = _cursor; }
/// <summary> /// <see cref="IWaitStrategy.WaitFor"/>. /// </summary> public long WaitFor(long sequence, Sequence cursor, ISequence dependentSequence, ISequenceBarrier barrier) { var milliseconds = _timeoutInMilliseconds; long availableSequence; if (cursor.Value < sequence) { lock (_lock) { while (cursor.Value < sequence) { Interlocked.Exchange(ref _signalNeeded, 1); barrier.CheckAlert(); if (!Monitor.Wait(_lock, milliseconds)) { throw TimeoutException.Instance; } } } } while ((availableSequence = dependentSequence.Value) < sequence) { barrier.CheckAlert(); } return availableSequence; }
/// <summary> /// Wait for the given sequence to be available /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">Ring buffer cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier) { long availableSequence; var spinWait = default(SpinWait); if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); spinWait.SpinOnce(); if (spinWait.Count > 5000) { break; } } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); spinWait.SpinOnce(); if (spinWait.Count > 5000) { break; } } } return(availableSequence); }
public long WaitOnLock(long sequence, Sequence cursorSequence, Sequence dependentSequence, ISequenceBarrier barrier, TimeSpan timeOut) { var availableSequence = cursorSequence.Value; // volatile read if (availableSequence < sequence) { Monitor.Enter(_gate); try { ++_numWaiters; while ((availableSequence = cursorSequence.Value) < sequence) // volatile read { barrier.CheckAlert(); Monitor.Wait(_gate, timeOut); } } finally { --_numWaiters; Monitor.Exit(_gate); } } while ((availableSequence = dependentSequence.Value) < sequence) { barrier.CheckAlert(); } return(availableSequence); }
/// <summary> /// Construct a <see cref="IBatchEventProcessor{TEvent}"/> that will automatically track the progress by updating its sequence when the <see cref="IEventHandler{TEvent}.OnEvent(TEvent,long,bool)"/> method returns. /// </summary> /// <param name="dataProvider">to which events are published.</param> /// <param name="sequenceBarrier">on which it is waiting.</param> /// <param name="eventHandler">is the delegate to which events are dispatched.</param> public BatchEventProcessor( IDataProvider <TEvent> dataProvider, ISequenceBarrier sequenceBarrier, IEventHandler <TEvent> eventHandler) : this(dataProvider, sequenceBarrier, eventHandler, null) { }
public void SetUp() { _ringBuffer = ValueRingBuffer <StubValueEvent> .CreateMultiProducer(() => new StubValueEvent(-1), 32); _sequenceBarrier = _ringBuffer.NewBarrier(); _ringBuffer.AddGatingSequences(new NoOpEventProcessor <StubValueEvent>(_ringBuffer).Sequence); }
internal EventHandlerGroup <T> CreateEventProcessors(IEventProcessor[] barrierEventProcessors, IEventHandler <T>[] eventHandlers, long startSequence = Sequencer.InitialCursorValue) { CheckNotStarted(); var createdEventProcessors = new IEventProcessor[eventHandlers.Length]; ISequenceBarrier barrier = _ringBuffer.NewBarrier(Util.GetSequencesFor(barrierEventProcessors)); for (int i = 0; i < eventHandlers.Length; i++) { var eventHandler = eventHandlers[i]; var batchEventProcessor = new BatchEventProcessor <T>(_ringBuffer, barrier, eventHandler, startSequence); if (_exceptionHandler != null) { batchEventProcessor.SetExceptionHandler(_exceptionHandler); } _eventProcessorRepository.Add(batchEventProcessor, eventHandler, barrier); createdEventProcessors[i] = batchEventProcessor; } if (createdEventProcessors.Length > 0) { _eventProcessorRepository.UnmarkEventProcessorsAsEndOfChain(barrierEventProcessors); } return(new EventHandlerGroup <T>(this, _eventProcessorRepository, createdEventProcessors)); }
/// <summary> /// Wait for the given sequence to be available with a timeout specified. /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the processor is waiting on.</param> /// <param name="timeout">timeout value to abort after.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> /// <exception cref="AlertException">AlertException if the status of the Disruptor has changed.</exception> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier, TimeSpan timeout) { long availableSequence; var spinWait = new SpinWait(); var sw = Stopwatch.StartNew(); if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); spinWait.SpinOnce(); if (sw.Elapsed > timeout) { break; } } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); spinWait.SpinOnce(); if (sw.Elapsed > timeout) { break; } } } return(availableSequence); }
/// <summary> /// Wait for the given sequence to be available with a timeout specified. /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the processor is waiting on.</param> /// <param name="timeout">timeout value to abort after.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> /// <exception cref="AlertException">AlertException if the status of the Disruptor has changed.</exception> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier, TimeSpan timeout) { long availableSequence; var counter = 0; var sw = Stopwatch.StartNew(); if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { counter = ApplyWaitMethod(barrier, counter); if (sw.Elapsed > timeout) { break; } } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { counter = ApplyWaitMethod(barrier, counter); if (sw.Elapsed > timeout) { break; } } } return availableSequence; }
public override long waitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier) { long availableSequence; if ((availableSequence = cursor.get()) < sequence) { lock (_lock) { try { ++numWaiters; while ((availableSequence = cursor.get()) < sequence) { barrier.checkAlert(); Monitor.Wait(_lock); } } finally { --numWaiters; } } } if (0 != dependents.Length) { while ((availableSequence = Util.getMinimumSequence(dependents)) < sequence) { barrier.checkAlert(); } } return availableSequence; }
public long WaitFor( long sequence, ISequence cursor, ISequence dependentSequence, ISequenceBarrier barrier) { var timeoutInMillis = _timeoutInMillis; if (cursor.GetValue() < sequence) { lock (_mutex) { while (cursor.GetValue() < sequence) { barrier.CheckAlert(); if (!Monitor.Wait(_mutex, timeoutInMillis)) { throw new TimeoutException(); } } } } long availableSequence; while ((availableSequence = dependentSequence.GetValue()) < sequence) { barrier.CheckAlert(); } return(availableSequence); }
/// <summary> /// Wait for the given sequence to be available with a timeout specified. /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the processor is waiting on.</param> /// <param name="timeout">timeout value to abort after.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> /// <exception cref="AlertException">AlertException if the status of the Disruptor has changed.</exception> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier, TimeSpan timeout) { long availableSequence; if ((availableSequence = cursor.Value) < sequence) { Monitor.Enter(_gate); try { while ((availableSequence = cursor.Value) < sequence) { barrier.CheckAlert(); if (!Monitor.Wait(_gate, timeout)) { break; } } } finally { Monitor.Exit(_gate); } } if (dependents.Length != 0) { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); } } return availableSequence; }
public Ring_Buffer_Test() { _ringBuffer = RingBuffer <StubEvent> .CreateMultiProducer(StubEvent.EventFactory, 32); _barrier = _ringBuffer.NewBarrier(); _ringBuffer.AddGatingSequences(new NoOpEventProcessor <StubEvent>(_ringBuffer).GetSequence()); }
public EventProcessorInfo(IEventProcessor eventProcessor, object eventHandler, ISequenceBarrier barrier) { EventProcessor = eventProcessor; Handler = eventHandler; Barrier = barrier; IsEndOfChain = true; }
public Batch_Event_Processor_Test(ObjectContainerFixture provider) { _ringBuffer = RingBuffer <StubEvent> .CreateMultiProducer(StubEvent.EventFactory, 16); _barrier = _ringBuffer.NewBarrier(); _exceptionHandler = provider.Services.GetService <IExceptionHandler <StubEvent> >(); }
public TimeoutBlockingWaitStrategyTest() { _barrier = new DummySequenceBarrier(); _strategy = new TimeoutBlockingWaitStrategy(TimeoutMilliseconds); _cursor = new Sequence(5); _dependent = _cursor; }
public OneToThreeSequencedThroughputTest() : base(Test_Disruptor, ITERATIONS,7) { ThreadPool.SetMaxThreads(NUM_EVENT_PROCESSORS,NUM_EVENT_PROCESSORS); for (long i = 0; i < ITERATIONS; i++) { results[0] = Operation.Addition.Op(results[0], i); results[1] = Operation.Substraction.Op(results[1], i); results[2] = Operation.And.Op(results[2], i); } sequenceBarrier = ringBuffer.NewBarrier(); handlers[0] = new ValueMutationEventHandler_v3(Operation.Addition); handlers[1] = new ValueMutationEventHandler_v3(Operation.Substraction); handlers[2] = new ValueMutationEventHandler_v3(Operation.And); batchEventProcessors[0] = new BatchEventProcessor<ValueEvent>(ringBuffer, sequenceBarrier, handlers[0]); batchEventProcessors[1] = new BatchEventProcessor<ValueEvent>(ringBuffer, sequenceBarrier, handlers[1]); batchEventProcessors[2] = new BatchEventProcessor<ValueEvent>(ringBuffer, sequenceBarrier, handlers[2]); ringBuffer.AddGatingSequences( batchEventProcessors[0].Sequence, batchEventProcessors[1].Sequence, batchEventProcessors[2].Sequence); }
/// <summary> /// Wait for the given sequence to be available with a timeout specified. /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the processor is waiting on.</param> /// <param name="timeout">timeout value to abort after.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> /// <exception cref="AlertException">AlertException if the status of the Disruptor has changed.</exception> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier, TimeSpan timeout) { long availableSequence; var counter = SpinTries; var sw = Stopwatch.StartNew(); if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { counter = ApplyWaitMethod(barrier, counter); if (sw.Elapsed > timeout) { break; } } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { counter = ApplyWaitMethod(barrier, counter); if (sw.Elapsed > timeout) { break; } } } return(availableSequence); }
/// <summary> /// Construct a <see cref="WorkProcessor{T}"/>. /// </summary> /// <param name="ringBuffer">to which events are published.</param> /// <param name="barrier">on which it is waiting.</param> /// <param name="workHandler">is the delegate to which events are dispatched.</param> /// <param name="exceptionHandler">to be called back when an error occurs.</param> /// <param name="workSequence">from which to claim the next event to be worked on. It should always be initialised <see cref="Sequence.InitialValue"/></param> public WorkProcessor( RingBuffer <T> ringBuffer, ISequenceBarrier barrier, IWorkHandler <T> workHandler, IExceptionHandler <T> exceptionHandler, ISequence workSequence) { _ringBuffer = ringBuffer; _barrier = barrier; _workHandler = workHandler; _exceptionHandler = exceptionHandler; _workSequence = workSequence; _sequence = new Sequence(); if (_workHandler is ITimeoutHandler timeoutHandler) { _timeoutHandler = timeoutHandler; } if (_workHandler is ILifecycleAware lifecycleAware) { _lifecycleAware = lifecycleAware; } if (_workHandler is IEventReleaseAware eventReleaseAware) { _eventReleaser = new EventReleaser(_sequence); eventReleaseAware.SetEventReleaser(_eventReleaser); } }
public EventProcessorInfo(IEventProcessor eventProcessor, IEventHandler <T> eventHandler, ISequenceBarrier sequenceBarrier) { EventProcessor = eventProcessor; EventHandler = eventHandler; SequenceBarrier = sequenceBarrier; IsEndOfChain = true; }
/// <summary> /// Wait for the given sequence to be available /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">Ring buffer cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier) { var availableSequence = cursor.Value; // volatile read if (availableSequence < sequence) { Monitor.Enter(_gate); try { ++_numWaiters; while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); Monitor.Wait(_gate); } } finally { --_numWaiters; Monitor.Exit(_gate); } } if (dependents.Length != 0) { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); } } return(availableSequence); }
/// <summary> /// Wait for the given sequence to be available with a timeout specified. /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the processor is waiting on.</param> /// <param name="timeout">timeout value to abort after.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> /// <exception cref="AlertException">AlertException if the status of the Disruptor has changed.</exception> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier, TimeSpan timeout) { long availableSequence; var spinWait = default(SpinWait); var sw = Stopwatch.StartNew(); if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); spinWait.SpinOnce(); if (sw.Elapsed > timeout) { break; } } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); spinWait.SpinOnce(); if (sw.Elapsed > timeout) { break; } } } return availableSequence; }
/// <summary> /// Construct a <see cref="IBatchEventProcessor{TEvent}"/> that will automatically track the progress by updating its sequence when the <see cref="IEventHandler{TEvent}.OnEvent(TEvent,long,bool)"/> method returns. /// </summary> /// <param name="exceptionHandler"></param> /// <param name="dataProvider">to which events are published.</param> /// <param name="sequenceBarrier">on which it is waiting.</param> /// <param name="eventHandler">is the delegate to which events are dispatched.</param> public BatchEventProcessor( IDataProvider <TEvent> dataProvider, ISequenceBarrier sequenceBarrier, IEventHandler <TEvent> eventHandler, IExceptionHandler <TEvent> exceptionHandler) { _exceptionHandler = exceptionHandler; _dataProvider = dataProvider; _sequenceBarrier = sequenceBarrier; _eventHandler = eventHandler; _sequence = new Sequence(); if (eventHandler is ISequenceReportingEventHandler <TEvent> reporting) { reporting?.SetSequenceCallback(_sequence); } if (eventHandler is IBatchStartAware batchStartAware) { _batchStartAware = batchStartAware; } if (eventHandler is ITimeoutHandler timeoutHandler) { _timeoutHandler = timeoutHandler; } if (eventHandler is ILifecycleAware lifecycleAware) { _lifecycleAware = lifecycleAware; } }
public long Start() { OzzyLogger <IDomainModelTracing> .Log.TraceInformationalEvent("Start event loop"); if (Interlocked.CompareExchange(ref _stage, 1, 0) == 0) { var minCheckpoint = 0L; var checkpoints = _eventProcessors.Select(e => e.GetCheckpoint()).ToList(); if (checkpoints.Any()) { minCheckpoint = checkpoints.Min(); } _disruptor = new Disruptor <DomainEventEntry>(() => new DomainEventEntry(), new MultiThreadedClaimStrategy(_bufferSize), _waitStrategy ?? new BlockingWaitStrategy(), TaskScheduler.Default, minCheckpoint); _disruptor.HandleExceptionsWith(_exceptionHandler); foreach (var domainEventsProcessor in _eventProcessors) { _disruptor.HandleEventsWith(domainEventsProcessor.GetCheckpoint(), domainEventsProcessor); } _ringBuffer = _disruptor.Start(); _barrier = _ringBuffer.NewBarrier(); StartCursorSupervisor(minCheckpoint, TimeSpan.FromMilliseconds(_pollTimeout)); Interlocked.Exchange(ref _stage, 2); return(minCheckpoint); } else { throw new InvalidOperationException("Domain Manager already started"); } }
private IEventProcessor[] GetRequestSenders( RingBuffer <EventType> ringBuffer, ISequenceBarrier sequenceBarrier, RequestSenderMode mode) { var mockExternalService = new MockExternalService <OutgoingRequest, int>(); AsyncExtensions.FireAndForgetLongRunning( () => mockExternalService.Run(), (ex) => Assert.Fail(ex.StackTrace) ); var createOrUpdateRequestExecutor = new RequestSender <EventType, OutgoingRequest>( (@event) => @event.CreateOrUpdateTodoListRequest, mockExternalService, mode, (ex) => Assert.Fail(ex.StackTrace) ); var deleteRequestExecutor = new RequestSender <EventType, OutgoingRequest>( (@event) => @event.DeleteTodoListsRequest, mockExternalService, mode, (ex) => Assert.Fail(ex.StackTrace) ); var removeItemsRequestExecutor = new RequestSender <EventType, OutgoingRequest>( (@event) => @event.RemoveLineItemsRequest, mockExternalService, mode, (ex) => Assert.Fail(ex.StackTrace) ); return(new IEventProcessor[] { new AsyncEventProcessor <EventType>( ringBuffer, sequenceBarrier, new SpinLock(), createOrUpdateRequestExecutor ), new AsyncEventProcessor <EventType>( ringBuffer, sequenceBarrier, new SpinLock(), deleteRequestExecutor ), new AsyncEventProcessor <EventType>( ringBuffer, sequenceBarrier, new SpinLock(), removeItemsRequestExecutor ), }); }
public TestWaiter(Barrier barrier, ISequenceBarrier sequenceBarrier, RingBuffer <StubEvent> ringBuffer, long initialSequence, long toWaitForSequence) { _barrier = barrier; _sequenceBarrier = sequenceBarrier; _ringBuffer = ringBuffer; _initialSequence = initialSequence; _toWaitForSequence = toWaitForSequence; }
public void Add(IEventProcessor eventProcessor, object eventHandler, ISequenceBarrier sequenceBarrier) { var consumerInfo = new EventProcessorInfo(eventProcessor, eventHandler, sequenceBarrier); _eventProcessorInfoByEventHandler[eventHandler] = consumerInfo; _eventProcessorInfoBySequence[eventProcessor.Sequence] = consumerInfo; _consumerInfos.Add(consumerInfo); }
public TestWaiter(Barrier barrier, ISequenceBarrier sequenceBarrier, RingBuffer<StubEvent> ringBuffer, long initialSequence, long toWaitForSequence) { _barrier = barrier; _sequenceBarrier = sequenceBarrier; _ringBuffer = ringBuffer; _initialSequence = initialSequence; _toWaitForSequence = toWaitForSequence; }
public BatchEventProcessorBenchmarks() { _ringBuffer = new RingBuffer <TestEvent>(() => new TestEvent(), new SingleProducerSequencer(4096, new SpinWaitWaitStrategy())); _eventHandler = new TestEventHandler(); _sequenceBarrier = _ringBuffer.NewBarrier(); _ringBuffer.PublishEvent().Dispose(); }
public OneToOneSequencedBatchThroughputTest() : base(Test_Disruptor, ITERATIONS, 7) { ThreadPool.SetMaxThreads(4, 4); sequenceBarrier = ringBuffer.NewBarrier(); batchEventProcessor = new BatchEventProcessor <ValueEvent>(ringBuffer, sequenceBarrier, handler); ringBuffer.AddGatingSequences(batchEventProcessor.Sequence); }
public OneToOneSequencedLongArrayThroughputTest() : base(Test_Disruptor, ITERATIONS,7) { ThreadPool.SetMaxThreads (1,1); sequenceBarrier = ringBuffer.NewBarrier(); batchEventProcessor = new BatchEventProcessor<long[]>(ringBuffer, sequenceBarrier, handler); ringBuffer.AddGatingSequences(batchEventProcessor.Sequence); }
/// <summary> /// Construct a <see cref="WorkProcessor{T}"/>. /// </summary> /// <param name="ringBuffer">ringBuffer to which events are published.</param> /// <param name="sequenceBarrier">sequenceBarrier on which it is waiting.</param> /// <param name="workHandler">workHandler is the delegate to which events are dispatched.</param> /// <param name="exceptionHandler">exceptionHandler to be called back when an error occurs</param> /// <param name="workSequence">workSequence from which to claim the next event to be worked on. It should always be initialised /// as <see cref="Sequencer.InitialCursorValue"/></param> public WorkProcessor(RingBuffer <T> ringBuffer, ISequenceBarrier sequenceBarrier, IWorkHandler <T> workHandler, IExceptionHandler exceptionHandler, Sequence workSequence) { _ringBuffer = ringBuffer; _sequenceBarrier = sequenceBarrier; _workHandler = workHandler; _exceptionHandler = exceptionHandler; _workSequence = workSequence; }
public OnePublisherToOneProcessorUniCastThroughputTest() : base("Disruptor", ITERATIONS) { sequenceBarrier = ringBuffer.NewBarrier(); batchEventProcessor = new BatchEventProcessor <ValueEvent>(ringBuffer, sequenceBarrier, disruptorHandler); ringBuffer.AddGatingSequences(batchEventProcessor.Sequence); //queueHandler = new ValueAdditionQueueProcessor_V3(blockQueue, ITERATIONS - 1); }
public OnePublisherToOneProcessorUniCastThroughputTest() : base("Disruptor", ITERATIONS) { sequenceBarrier = ringBuffer.NewBarrier(); batchEventProcessor = new BatchEventProcessor<ValueEvent>(ringBuffer, sequenceBarrier, disruptorHandler); ringBuffer.AddGatingSequences(batchEventProcessor.Sequence); //queueHandler = new ValueAdditionQueueProcessor_V3(blockQueue, ITERATIONS - 1); }
public void Setup() { _ringBuffer = new RingBuffer <StubEvent>(() => new StubEvent(-1), 16); _sequenceBarrier = _ringBuffer.NewBarrier(); _batchHandlerMock = new Mock <IEventHandler <StubEvent> >(); _countDownEvent = new CountdownEvent(1); _batchEventProcessor = new BatchEventProcessor <StubEvent>(_ringBuffer, _sequenceBarrier, _batchHandlerMock.Object); _ringBuffer.AddGatingSequences(_batchEventProcessor.Sequence); }
public RingBufferConsumer( IRingBuffer <TMessage> messageQueue, ISequenceBarrier sequenceBarrier, IMessageHandler <TMessage> batchMessageHandler) { this._messageBuffer = messageQueue; this._sequenceBarrier = sequenceBarrier; this._batchMessageHandler = batchMessageHandler; }
public EventProcessorInfo( IEventProcessor processor, IEventHandler <T> handler, ISequenceBarrier barrier) { _processor = processor; _handler = handler; _barrier = barrier; }
public void Setup() { _ringBuffer = new RingBuffer<StubEvent>(()=>new StubEvent(-1), 16); _sequenceBarrier = _ringBuffer.NewBarrier(); _batchHandlerMock = new Mock<IEventHandler<StubEvent>>(); _countDownEvent = new CountdownEvent(1); _batchEventProcessor = new BatchEventProcessor<StubEvent>(_ringBuffer, _sequenceBarrier, _batchHandlerMock.Object); _ringBuffer.AddGatingSequences(_batchEventProcessor.Sequence); }
/// <summary> /// Construct a <see cref="BatchEventProcessor{T}"/> that will automatically track the progress by updating its sequence when /// the <see cref="IEventHandler{T}.OnEvent"/> method returns. /// </summary> /// <param name="dataProvider">dataProvider to which events are published</param> /// <param name="sequenceBarrier">SequenceBarrier on which it is waiting.</param> /// <param name="eventHandler">eventHandler is the delegate to which events are dispatched.</param> public BatchEventProcessor(IDataProvider <T> dataProvider, ISequenceBarrier sequenceBarrier, IEventHandler <T> eventHandler) { _dataProvider = dataProvider; _sequenceBarrier = sequenceBarrier; _eventHandler = eventHandler; (eventHandler as ISequenceReportingEventHandler <T>)?.SetSequenceCallback(_sequence); _timeoutHandler = eventHandler as ITimeoutHandler; }
public ThreeToOneSequencedThroughputTest() { _sequenceBarrier = _ringBuffer.NewBarrier(); _batchEventProcessor = new BatchEventProcessor<ValueEvent>(_ringBuffer, _sequenceBarrier, _handler); for (var i = 0; i < _numPublishers; i++) { _valuePublishers[i] = ValuePublisher; } _ringBuffer.AddGatingSequences(_batchEventProcessor.Sequence); }
/// <summary> /// <see cref="IWaitStrategy.WaitFor"/> /// </summary> public long WaitFor(long sequence, Sequence cursor, ISequence dependentSequence, ISequenceBarrier barrier) { long availableSequence; while ((availableSequence = dependentSequence.Value) < sequence) { barrier.CheckAlert(); } return availableSequence; }
public TestWaiter(CyclicBarrier cyclicBarrier, ISequenceBarrier sequenceBarrier, RingBuffer<StubEvent> ringBuffer, long initialSequence, long toWaitForSequence) { this.cyclicBarrier = cyclicBarrier; this.initialSequence = initialSequence; this.ringBuffer = ringBuffer; this.toWaitForSequence = toWaitForSequence; this.sequenceBarrier = sequenceBarrier; }
/// <summary> /// Wait for the given sequence to be available. It is possible for this method to return a value /// less than the sequence number supplied depending on the implementation of the WaitStrategy. A common /// use for this is to signal a timeout. Any EventProcessor that is using a WaitStragegy to get notifications /// about message becoming available should remember to handle this case. The {@link BatchEventProcessor} explicitly /// handles this case and will signal a timeout if required. /// </summary> /// <param name="sequence">to be waited on.</param> /// <param name="cursor">the main sequence from ringbuffer. Wait/notify strategies will need this as it's the only sequence that is also notified upon update.</param> /// <param name="dependentSequence">on which to wait.</param> /// <param name="barrier">the processor is waiting on.</param> /// <returns></returns> /// <exception cref="AlertException">if the status of the Disruptor has changed.</exception> /// <exception cref="System.Threading.ThreadInterruptedException">if the thread is interrupted.</exception> /// <exception cref="TimeoutException"></exception> /// Date:2013/8/27 /// Author:liguo public long WaitFor(long sequence, Sequence cursor, Sequence dependentSequence, ISequenceBarrier barrier) { long availableSequence; int counter = RETRIES; while ((availableSequence = dependentSequence.Value) < sequence) { counter = ApplyWaitMethod(barrier, counter); } return availableSequence; }
public ThreeToOneSequencedBatchThroughputTest() : base(Test_Disruptor, ITERATIONS,7) { ThreadPool.SetMaxThreads (4,4); sequenceBarrier = ringBuffer.NewBarrier(); batchEventProcessor = new BatchEventProcessor<ValueEvent>(ringBuffer, sequenceBarrier, handler); for (int i = 0; i < NUM_PUBLISHERS; i++) { valuePublishers[i] = new ValueBatchPublisher(cyclicBarrier, ringBuffer, ITERATIONS / NUM_PUBLISHERS, 10); } ringBuffer.AddGatingSequences(batchEventProcessor.Sequence); }
private int ApplyWaitMethod(ISequenceBarrier barrier, int counter) { barrier.CheckAlert(); if (0 == counter) { Thread.Yield (); } else { --counter; } return counter; }
public TwoPublisherToTwoProcessorWorkProcessorThroughputTest() : base(TestName, ITERATIONS) { sequenceBarrier = ringBuffer.NewBarrier(); workProcessors[0] = new WorkProcessor<ValueEvent>(ringBuffer, sequenceBarrier, handlers[0], new IgnoreExceptionHandler(), workSequence); workProcessors[1] = new WorkProcessor<ValueEvent>(ringBuffer, sequenceBarrier, handlers[1], new IgnoreExceptionHandler(), workSequence); //workerPool = new WorkerPool<ValueEvent>(ringBuffer, sequenceBarrier, new IgnoreExceptionHandler(), handlers); for (int i = 0; i < NUM_PUBLISHERS; i++) { valuePublishers[i] = new ValuePublisher_V3(cyclicBarrier, ringBuffer, ITERATIONS); } workProcessors.ToList().ForEach(e => ringBuffer.AddGatingSequences(e.Sequence)); //ringBuffer.AddGatingSequences(/*workerPool.getWorkerSequences()*/workProcessors[0].Sequence, workProcessors[1].Sequence); }
private static int ApplyWaitMethod(ISequenceBarrier barrier, int counter) { barrier.CheckAlert(); if (counter > 100) { --counter; } else if (counter > 0) { --counter; Thread.Yield(); } else { Thread.Sleep(0); } return counter; }
/// <summary> /// Wait for the given sequence to be available /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">Ring buffer cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier) { long availableSequence; if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); } } return availableSequence; }
private int ApplyWaitMethod(ISequenceBarrier barrier, int counter) { barrier.CheckAlert(); if (counter > 100) { --counter; } else if (counter > 0) { --counter; Thread.Sleep(0); } else { spinWait.SpinOnce(); //LockSupport.parkNanos(1L); } return counter; }
/// <summary> /// <see cref="IWaitStrategy.WaitFor"/> /// </summary> public long WaitFor(long sequence, Sequence cursor, ISequence dependentSequence, ISequenceBarrier barrier) { if (cursor.Value < sequence) { lock (_gate) { while (cursor.Value < sequence) { barrier.CheckAlert(); Monitor.Wait(_gate); } } } long availableSequence; while ((availableSequence = dependentSequence.Value) < sequence) { barrier.CheckAlert(); } return availableSequence; }
/// <summary> /// Wait for the given sequence to be available /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">Ring buffer cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier) { long availableSequence; var counter = 0; if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { counter = ApplyWaitMethod(barrier, counter); } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { counter = ApplyWaitMethod(barrier, counter); } } return availableSequence; }
public TwoToTwoWorkProcessorThroughputTest() : base(Test_Disruptor, ITERATIONS) { sequenceBarrier = ringBuffer.NewBarrier(); handlers[0] = new ValueAdditionWorkHandler(); handlers[1] = new ValueAdditionWorkHandler(); workProcessors[0] = new WorkProcessor<ValueEvent>(ringBuffer, sequenceBarrier, handlers[0], new IgnoreExceptionHandler(), workSequence); workProcessors[1] = new WorkProcessor<ValueEvent>(ringBuffer, sequenceBarrier, handlers[1], new IgnoreExceptionHandler(), workSequence); for (int i = 0; i < NUM_PUBLISHERS; i++) { valuePublishers[i] = new ValuePublisher(cyclicBarrier, ringBuffer, ITERATIONS); } ringBuffer.AddGatingSequences(workProcessors[0].Sequence, workProcessors[1].Sequence); }
public long WaitFor(long sequence, Sequence cursor, Sequence dependentSequence, ISequenceBarrier barrier) { long availableSequence; if ((availableSequence = dependentSequence.Value) < sequence) { bool lockToken = false; Monitor.Enter(obj, ref lockToken); try { do { signalNeeded.WriteFullFence(true); if ((availableSequence = dependentSequence.Value) >= sequence) { break; } barrier.CheckAlert(); Monitor.Wait(obj); } while ((availableSequence = dependentSequence.Value) < sequence); } finally { if (lockToken) Monitor.Exit(obj); } } while ((availableSequence = dependentSequence.Value) < sequence) { barrier.CheckAlert(); } return availableSequence; }
/// <summary> /// Wait for the given sequence to be available. It is possible for this method to return a value /// less than the sequence number supplied depending on the implementation of the WaitStrategy. A common /// use for this is to signal a timeout. Any EventProcessor that is using a WaitStragegy to get notifications /// about message becoming available should remember to handle this case. The {@link BatchEventProcessor} explicitly /// handles this case and will signal a timeout if required. /// </summary> /// <param name="sequence">to be waited on.</param> /// <param name="cursor">the main sequence from ringbuffer. Wait/notify strategies will need this as it's the only sequence that is also notified upon update.</param> /// <param name="dependentSequence">on which to wait.</param> /// <param name="barrier">the processor is waiting on.</param> /// <returns></returns> /// <exception cref="AlertException">if the status of the Disruptor has changed.</exception> /// <exception cref="System.Threading.ThreadInterruptedException">if the thread is interrupted.</exception> /// <exception cref="TimeoutException"></exception> /// Date:2013/8/27 /// Author:liguo public long WaitFor(long sequence, Sequence cursor, Sequence dependentSequence, ISequenceBarrier barrier) { long availableSequence; long startTime = 0; int counter = SPIN_TRIES; var stopWatch = Stopwatch.StartNew(); do { if ((availableSequence = dependentSequence.Value) >= sequence) { return availableSequence; } if (0 == --counter) { if (0 == startTime) { startTime = stopWatch.ElapsedTicks; } else { var timeDelta = stopWatch.Elapsed; if (timeDelta > yieldTimeoutNanos) { return lockingStrategy.WaitOnLock(sequence, cursor, dependentSequence, barrier, spinTimeoutNanos); } else if (timeDelta > spinTimeoutNanos) { Thread.Sleep(0); } } counter = SPIN_TRIES; } } while (true); }
public MyRunnable(ISequencer sequencer) { _barrier = sequencer.NewBarrier(); }