private Task <DispatchResult> EnqueueInvocation(ExecutableEvent message) { var tcs = new TaskCompletionSource <DispatchResult>(); var dispatch = new MessageDispatch(MessageContext.CreateTest(), message, (d, r) => tcs.SetResult(r)); dispatch.SetHandlerCount(1); var invoker = new TestMessageHandlerInvoker <ExecutableEvent>(); _dispatchQueue.Enqueue(dispatch, invoker); return(tcs.Task); }
public async Task ShouldCreateADispatchQueueAndEnqueueMessagesThenDispose(int batchSize, int queueMaxSize, int messageCount, int messageConsumptionWait) { var messages = new List <IEvent>(); var dispatchQueueConfiguration = new DispatchQueueConfiguration( async(m) => { messages.Add(m); await Task.Delay(messageConsumptionWait + 5); }, batchSize, queueMaxSize ); var dispatchQueue = new DispatchQueue("void", dispatchQueueConfiguration, new DummyLoggerFactory()); Assert.True(dispatchQueue.CanEnqueue()); await Task.Delay(100); for (var i = 0; i < messageCount; i++) { dispatchQueue.Enqueue(new TestMessage(i)); } await Task.Delay(messageConsumptionWait *batchSize); Assert.AreEqual(batchSize, messages.Count); dispatchQueue.Dispose(); Assert.IsFalse(dispatchQueue.CanEnqueue()); Assert.AreEqual(messageCount, messages.Count); }
private async Task Loop() { var dispatchQueue = new DispatchQueue <UdpReceiveResult>((result) => { var buffer = DataBuffer.Wrap(result.Buffer); var header = RtpPacketHeader.ReadFrom(buffer); try { OnPacket?.Invoke(new RtpPacket(buffer.Subset(header.CalculateHeaderLength()), header.SequenceNumber, header.Timestamp, header.Marker) { PayloadType = header.PayloadType, SynchronizationSource = header.SynchronizationSource }); } catch (Exception ex) { Console.Error.WriteLine($"Unexpected exception raising packet. {ex}"); } }); while (_LoopActive) { try { dispatchQueue.Enqueue(await _Server.ReceiveAsync()); } catch (ObjectDisposedException) { break; } } dispatchQueue.WaitForDrain(); dispatchQueue.Destroy(); }
public async Task ShouldTryToEnqueueAndKillApp(bool shouldCrashApp) { var killSwitch = Substitute.For <IKillSwitch>(); var message1 = new TestMessage(0); var message2 = new TestMessage(1); var dispatchQueueConfiguration = new DispatchQueueConfiguration( (m) => { if ((m as TestEvent).Value == message1.Value) { throw new Exception("boom"); } return(Task.CompletedTask); }, 10, 10, shouldCrashApp); var dispatchQueue = new DispatchQueue("void", dispatchQueueConfiguration, new DummyLoggerFactory(), killSwitch); dispatchQueue.Enqueue(message1); dispatchQueue.Enqueue(message2); await Task.Delay(100); killSwitch.Received(shouldCrashApp ? 1 : 0).KillProcess(Arg.Any <Exception>()); if (shouldCrashApp) { Assert.IsFalse(message1.IsAcknowledge); Assert.IsFalse(message2.IsAcknowledge); Assert.IsFalse(dispatchQueue.CanEnqueue()); Assert.IsTrue(dispatchQueue.IsFaulted); } else { Assert.IsFalse(message1.IsAcknowledge); Assert.IsTrue(message2.IsAcknowledge); Assert.IsTrue(dispatchQueue.CanEnqueue()); Assert.IsFalse(dispatchQueue.IsFaulted); } }
public void should_continue_processing_messages_after_continuation_error() { _dispatchQueue.Start(); var message1 = new ExecutableEvent { Callback = x => throw new Exception("Processing error") }; var dispatch = new MessageDispatch(MessageContext.CreateTest(), message1, new TestMessageSerializer(), (d, r) => throw new Exception("Continuation error")); dispatch.SetHandlerCount(1); _dispatchQueue.Enqueue(dispatch, new TestMessageHandlerInvoker <ExecutableEvent>()); var message2 = new ExecutableEvent(); var task = EnqueueInvocation(message2); task.Wait(5.Seconds()).ShouldBeTrue(); }
public async Task ShouldNackAllMessagesAfterACriticalFailure() { var killSwitch = Substitute.For <IKillSwitch>(); var dispatchQueueConfiguration = new DispatchQueueConfiguration( (m) => { if ((m as TestEvent).Value == 1) { throw new Exception("boom"); } return(Task.CompletedTask); }, 10, 10, true); var dispatchQueue = new DispatchQueue("void", dispatchQueueConfiguration, new DummyLoggerFactory(), killSwitch); var messages = new List <TestMessage>(); var i = 0; while (dispatchQueue.CanEnqueue() && messages.Count < 100) { var message = new TestMessage(i++); messages.Add(message); dispatchQueue.Enqueue(message); } await Task.Delay(100); Assert.IsFalse(dispatchQueue.CanEnqueue()); Assert.IsTrue(dispatchQueue.IsFaulted); Assert.IsTrue(messages.First().IsAcknowledge); foreach (var message in messages.Skip(1)) { Assert.IsFalse(message.IsAcknowledge); } }
public void ShouldTryToEnqueueAndFail() { var dispatchQueueConfiguration = new DispatchQueueConfiguration( async(m) => { await Task.Delay(10); }, 10, 10 ); var dispatchQueue = new DispatchQueue("void", dispatchQueueConfiguration, new DummyLoggerFactory()); dispatchQueue.Dispose(); Assert.IsFalse(dispatchQueue.CanEnqueue()); Assert.Throws <InvalidOperationException>(() => dispatchQueue.Enqueue(new TestMessage(1))); }
public async Task ShouldResumeMessageProcessingAfterFailure() { var killSwitch = Substitute.For <IKillSwitch>(); var dispatchQueueConfiguration = new DispatchQueueConfiguration( (m) => { if ((m as TestEvent).Value == 2) { throw new Exception("boom"); } return(Task.CompletedTask); }, 10, 10, false); var dispatchQueue = new DispatchQueue("void", dispatchQueueConfiguration, new DummyLoggerFactory(), killSwitch); var messages = new List <TestMessage>(); var i = 0; while (dispatchQueue.CanEnqueue() && messages.Count < 100) { var message = new TestMessage(i++); messages.Add(message); dispatchQueue.Enqueue(message); } await Task.Delay(100); Assert.IsTrue(dispatchQueue.CanEnqueue()); Assert.IsFalse(dispatchQueue.IsFaulted); Assert.IsTrue(messages.Where(m => !m.IsAcknowledge).Count() == 1); }
public void Send <T>(T message) { _dispatchQueue.Enqueue(message); }