public void ShouldPollForEvents() { var pollSequence = new Sequence(); var bufferSequence = new Sequence(); var gatingSequence = new Sequence(); var sequencerMock = new Mock <ISequencer>(); var sequencer = sequencerMock.Object; var handled = false; Func <object, long, bool, bool> handler = (ev, seq, end) => { handled = true; return(false); }; var providerMock = new Mock <IDataProvider <object> >(); var provider = providerMock.Object; var poller = EventPoller <object> .NewInstance(provider, sequencer, pollSequence, bufferSequence, gatingSequence); var @event = new object(); object states = PollState.Idle; sequencerMock.SetupGet(x => x.Cursor) .Returns(() => { switch ((PollState)states) { case PollState.Processing: return(0L); case PollState.Gating: return(0L); case PollState.Idle: return(-1L); default: throw new ArgumentOutOfRangeException(); } }); sequencerMock.Setup(x => x.GetHighestPublishedSequence(0L, -1L)).Returns(-1L); sequencerMock.Setup(x => x.GetHighestPublishedSequence(0L, 0L)).Returns(0L); providerMock.Setup(x => x[0]).Returns(() => (PollState)states == PollState.Processing ? @event : null); // Initial State - nothing published. states = PollState.Idle; Assert.That(poller.Poll(handler), Is.EqualTo(PollState.Idle)); // Publish Event. states = PollState.Gating; bufferSequence.IncrementAndGet(); Assert.That(poller.Poll(handler), Is.EqualTo(PollState.Gating)); states = PollState.Processing; gatingSequence.IncrementAndGet(); Assert.That(poller.Poll(handler), Is.EqualTo(PollState.Processing)); Assert.That(handled, Is.True); }
public OneToOneSequencedPollerThroughputTest() { _ringBuffer = RingBuffer<ValueEvent>.CreateSingleProducer(ValueEvent.EventFactory, _bufferSize, new YieldingWaitStrategy()); _poller = _ringBuffer.NewPoller(); _ringBuffer.AddGatingSequences(_poller.Sequence); _pollRunnable = new PollRunnable(_poller); }
/// <summary> /// </summary> /// <param name="arg"></param> private async void SendOutgoingUdpMessages(object arg) { object[] args = (object[])arg; AsyncUdpSocketSender sender = (AsyncUdpSocketSender)args[0]; EventPoller <OutgoingUdpMessage> outgoingMessagePoller = (EventPoller <OutgoingUdpMessage>)args[1]; CancellationToken cancellation = (CancellationToken)args[2]; int eventsThisIteration = 0; while (!cancellation.IsCancellationRequested) { // poll for send events outgoingMessagePoller.Poll((m, s, eob) => { // Send udp message if (m.SendType == UdpSendType.SendTo) { sender.BeginSendTo(m.Buffer, 0, m.Size, m.Endpoint); } eventsThisIteration++; return(eventsThisIteration < MaxUdpMessageSendBeforeSleep); }); await Task.Delay(1, cancellation); } }
public BatchedPoller(RingBuffer <DataEvent> ringBuffer, int batchSize) { _poller = ringBuffer.NewPoller(); ringBuffer.AddGatingSequences(_poller.Sequence); _polledData = new BatchedData(batchSize); }
public OneToOneSequencedPollerThroughputTest() { _ringBuffer = RingBuffer <PerfEvent> .CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy()); _poller = _ringBuffer.NewPoller(); _ringBuffer.AddGatingSequences(_poller.Sequence); _pollRunnable = new PollRunnable(_poller); }
public OneToOneSequencedPollerThroughputTest() : base(Test_Disruptor, ITERATIONS, 7) { ThreadPool.SetMaxThreads(1, 1); poller = ringBuffer.NewPoller(); pollRunnable = new PollRunnable(poller); ringBuffer.AddGatingSequences(poller.GetSequence()); }
private PollState LoadNextValues(EventPoller <DataEvent> poller, BatchedData batch) { return(poller.Poll((ev, sequence, endOfBatch) => { var item = ev.CopyOfData(); return item != null && batch.AddDataItem(item); })); }
public OneToOneSequencedPollerThroughputTest() : base(Test_Disruptor, ITERATIONS,7) { ThreadPool.SetMaxThreads (1,1); poller = ringBuffer.NewPoller(); pollRunnable = new PollRunnable(poller); ringBuffer.AddGatingSequences(poller.GetSequence()); }
private static object GetNextValue(EventPoller <DataEvent <object> > poller) { var output = new object[1]; poller.Poll((ev, sequence, endOfBatch) => { output[0] = ev.CopyOfData(); return(false); }); return(output[0]); }
public BatchedPoller(RingBuffer <DataEvent> ringBuffer, int batchSize) { _poller = ringBuffer.NewPoller(); ringBuffer.AddGatingSequences(_poller.Sequence); if (batchSize < 1) { batchSize = 20; } _maxBatchSize = batchSize; _polledData = new BatchedData(_maxBatchSize); }
/// <summary> /// Creates an event poller for this sequence that will use the supplied data provider and /// gating sequences. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="provider">The data source for users of this event poller</param> /// <param name="gatingSequences">Sequence to be gated on.</param> /// <returns>A poller that will gate on this ring buffer and the supplied sequences.</returns> public EventPoller <T> NewPoller <T>(IDataProvider <T> provider, params ISequence[] gatingSequences) { return(EventPoller <T> .NewInstance(provider, this, new Sequence(), _cursor, gatingSequences)); }
public PollRunnable(EventPoller <PerfEvent> poller) { _poller = poller; _eventHandler = OnEvent; }
// Start is called before the first frame update private void Start() { // UDP Socket Listener/Sender initialization _socket = new UdpSocket(); _socketListener = new AsyncUdpSocketListener(_socket); _socketSender = new AsyncUdpSocketSender(_socket); // Add to RingBuffer from listener async callbacks which happen off the main thread _socketListener.ReceivedUdpMessageEvent += AddUdpMessageToReceivedBuffer; // Init ring buffers _receivedMessageBuffer = RingBuffer <UdpMessage> .Create( ProducerType.Single, UdpMessage.DefaultFactory, 256, new BusySpinWaitStrategy()); _receivedMessagePoller = _receivedMessageBuffer.NewPoller(); _receivedMessageBuffer.AddGatingSequences(_receivedMessagePoller.Sequence); _outgoingMessageBuffer = RingBuffer <OutgoingUdpMessage> .Create( ProducerType.Single, OutgoingUdpMessage.DefaultFactory, 256, new BusySpinWaitStrategy()); _outgoingMessagePoller = _outgoingMessageBuffer.NewPoller(); _outgoingMessageBuffer.AddGatingSequences(_outgoingMessagePoller.Sequence); // This makes a deep copy of the sent message before publishing it to the outgoing message buffer // It makes a deep copy because the buffers containing the data in the main thread could change // before the data has a chance to be copied into the ring buffer. Prob want to think of a way around this.. maybe more ring buffers _outgoingUdpMessageSender = new RingBufferOutgoingUdpMessageSender(_outgoingMessageBuffer); // The NetManager reactor. TODO: Benchmark and see if I have actually made any improvement by implementing disruptor // Though I do like the idea of clearing up the locks and doing all the logic in the main thread esp since // the game server will need to routinely access connected client info RNetManager = new NetManager(null, _outgoingUdpMessageSender) { DisconnectTimeout = 600 }; RGameReactor.RNetManager = RNetManager; _updateEvent = new GameEvent { EventId = GameEvent.Event.Update }; _tempEvent = new GameEvent(); // reusable event for the update loop //if (!ShouldBind) //{ //RNetManager.SimulateLatency = true; RNetManager.SimulatePacketLoss = true; // R_NetManager.SimulationMaxLatency = 10; // R_NetManager.SimulationMinLatency = 0; //} _cancellationSource = new CancellationTokenSource(); _processOutgoing = new Thread(SendOutgoingUdpMessages) { IsBackground = true, Name = "UdpServer" }; // Every frame the previous frames events get replaced with new output events created by the NetManager reactor for that frame _batchedEvents = new NetManagerEvent[MaxUdpMessagesPerFrame]; for (int i = 0; i < MaxUdpMessagesPerFrame; i++) { _batchedEvents[i] = new NetManagerEvent { EventId = NetManagerEvent.Event.UdpMessage } } ; // BIND if (ShouldBind) { _socket.BindLocalIpv4(BindAddress, BindPort); } // CONNECT - TEMPORARY - NEEDS TO BE SOME SORT OF STATE MACHINE if (ShouldConnect) { RNetManager.Connect(ConnectAddress, ConnectPort, "somekey"); } // No point actually awaiting this call.. it kicks off a // recurring execution where the finish method always calls the start method again #pragma warning disable 4014 _socketListener.StartAsyncReceive(); #pragma warning restore 4014 // Start thread that polls for outgoing udp messages and sends them on the socket _processOutgoing.Start(new object[] { _socketSender, _outgoingMessagePoller, _cancellationSource.Token }); // Start coroutine that will send the check timeout event StartCoroutine("SendCheckTimeoutEvent"); }
public PollRunnable(EventPoller<ValueEvent> poller) { _poller = poller; _eventHandler = OnEvent; }
/// <summary> /// <see cref="ISequencer.NewPoller{T}(IValueDataProvider{T}, ISequence[])"/>. /// </summary> public ValueEventPoller <T> NewPoller <T>(IValueDataProvider <T> provider, params ISequence[] gatingSequences) where T : struct { return(EventPoller.Create(provider, this, new Sequence(), _cursor, gatingSequences)); }
public PollRunnable(EventPoller <ValueEvent> poller) { this.poller = poller; }