public async Task ShouldDeadLetterAndDelete_When_MaxRetriesExceeded(int maxRetries, bool deadLetterMessages) { // arrange var options = new InboundTransportOptions("queue", maxRetries, deadLetterMessages); var deadLetterOptions = new InboundTransportOptions(options.GetDeadLetterEndpoint(), 1, false); var sender = this.factory.CreateOutboundTransport(); var receiver = this.factory.CreateInboundTransport(options); var deadletterReceiver = this.factory.CreateInboundTransport(deadLetterOptions); await sender.Send(CreateMessageFor(options.Endpoint)); IMessageTransaction msg; for (var i = 0; i < maxRetries - 1; ++i) { msg = await receiver.Receive(TimeSpan.FromMilliseconds(1)); await msg.Fail(); } // ensure dead letter is still empty var deadLetterMsg = await deadletterReceiver.Receive(TimeSpan.FromMilliseconds(1)); Assume.That(deadLetterMsg, Is.Null); // act // last attempt msg = await receiver.Receive(TimeSpan.FromMilliseconds(1)); await msg.Fail(); // assert msg = await receiver.Receive(TimeSpan.FromMilliseconds(1)); Assert.That(msg, Is.Null); deadLetterMsg = await deadletterReceiver.Receive(TimeSpan.FromMilliseconds(1)); if (deadLetterMessages) { Assert.That(deadLetterMsg, Is.Not.Null); Assert.That(deadLetterMsg.Message.Headers[MessageHeaders.OriginalEndpoint], Is.EqualTo(options.Endpoint)); } else { Assert.That(deadLetterMsg, Is.Null); } }
public async Task CanDoBasicBehavior() { var options = new InboundTransportOptions("queue"); var sender = this.factory.CreateOutboundTransport(); var receiver = this.factory.CreateInboundTransport(options); await sender.Send( new TransportMessage { Id = "id1", Name = "msg", Body = new Newtonsoft.Json.Linq.JObject() }.ForEndpoint(options.Endpoint)); var transaction = await receiver.Receive(TimeSpan.FromMilliseconds(5)); Assert.That(transaction.Message.Id, Is.EqualTo("id1")); Assert.That(transaction.DeliveryCount, Is.EqualTo(1)); await transaction.Commit(); transaction = await receiver.Receive(TimeSpan.FromMilliseconds(5)); //should be null because there are no more commands Assert.IsNull(transaction); await sender.Send( new TransportMessage { Id = "id2", Name = "msg", Body = new Newtonsoft.Json.Linq.JObject() }.ForEndpoint(options.Endpoint)); transaction = await receiver.Receive(TimeSpan.FromMilliseconds(5)); await transaction.Fail(); //should return to queue, to be retried transaction = await receiver.Receive(TimeSpan.FromMilliseconds(5)); //TODO: increase this timeout when defer times are supported on Fail Assert.NotNull(transaction); Assert.That(transaction.Message.Id, Is.EqualTo("id2")); Assert.That(transaction.DeliveryCount, Is.EqualTo(2)); await transaction.Commit(); transaction = await receiver.Receive(TimeSpan.FromMilliseconds(5)); //should return null because there are no more commands Assert.IsNull(transaction); }
public async Task ShouldReceiveMessage_When_ReceivingWithEmptyQueue_And_AMessageIsPublished() { var options = new InboundTransportOptions("queue"); var receiver = this.factory.CreateInboundTransport(options); var sender = this.factory.CreateOutboundTransport(); IMessageTransaction tr = null; var receiveTask = receiver.Receive().ContinueWith(t => tr = t.Result); await sender.Send(CreateMessageFor(options.Endpoint)); await Task.WhenAny(receiveTask, Task.Delay(2000)); //receiveTask.Wait(TimeSpan.FromSeconds(2)); // can cause deadlocks on sync contexts Assert.NotNull(tr); }
/// <summary> /// Configures the current processor instance with the previously specified settings. /// </summary> /// <param name="subscriptionManager">subscriptionManager</param> /// <param name="transportFactory">transportFactory</param> /// <param name="loggerFactory">loggerFactory</param> /// <param name="resolver">resolver</param> /// <returns>A configured IProcessor instance</returns> public IProcessor Configure(ISubscriptionManager subscriptionManager, ITransportFactory transportFactory, ILoggerFactory loggerFactory, IDependencyResolver resolver) { this.configurer(this); var options = new InboundTransportOptions(this.endpoint, this.maxDeliveryCount, this.deadLetterMessages); var processor = new Processor(options, this.concurrencyLevel, subscriptionManager, transportFactory, loggerFactory, resolver); // handlers can be registered here if (this.Configuring != null) { this.Configuring(processor); } return(processor); }
public Processor(InboundTransportOptions options, int concurrencyLevel, ISubscriptionManager subscriptionManager, ITransportFactory transportFactory, ILoggerFactory loggerFactory, IDependencyResolver resolver) { this.options = options; this.subscriptionManager = subscriptionManager; this.resolver = resolver; this.subscriptions = new HashSet <Subscription>(); this.registry = new Dictionary <string, Dictionary <string, IMessageHandler> >(); this.worker = new MessageWorker( transportFactory.CreateInboundTransport(options), new DiagnosticsDispatcher(this), // TODO: build proper pipeline support loggerFactory, concurrencyLevel); }