Beispiel #1
0
        public async Task VeryBasicTransactionThing()
        {
            const string destinationQueueName = "another-queue";

            var network = new InMemNetwork();

            network.CreateQueue(destinationQueueName);

            var transport = new InMemTransport(network, "test-queue");

            transport.Initialize();

            using (var scope = new RebusTransactionScope())
            {
                var headers = new Dictionary <string, string> {
                    { Headers.MessageId, Guid.NewGuid().ToString() }
                };

                await transport.Send(
                    destinationAddress : destinationQueueName,
                    message : new TransportMessage(headers, new byte[] { 1, 2, 3 }),
                    context : scope.TransactionContext
                    );

                Assert.That(network.Count(destinationQueueName), Is.EqualTo(0),
                            $"Expected ZERO messages in queue '{destinationQueueName}' at this point, because the scope was not completed");

                await scope.CompleteAsync();
            }

            Assert.That(network.Count(destinationQueueName), Is.EqualTo(1),
                        $"Expected 1 message in queue '{destinationQueueName}' at this point, because the scope is completed now");
        }
        public async Task UnregisterSubscriber(string topic, string subscriberAddress)
        {
            m_log.Debug(c_removingSqsSubscriptionMessage, subscriberAddress, topic);
            using (var rebusTransactionScope = new RebusTransactionScope())
            {
                var topicArn = await m_AmazonInternalSettings.GetTopicArn(topic, rebusTransactionScope);

                using (var scope = new RebusTransactionScope())
                {
                    var destinationQueueUrlByName = m_amazonSQSQueueContext.GetDestinationQueueUrlByName(subscriberAddress, scope.TransactionContext);

                    var sqsInfo = m_amazonSQSQueueContext.GetSqsInformationFromUri(destinationQueueUrlByName);

                    var snsClient = m_AmazonInternalSettings.CreateSnsClient(rebusTransactionScope.TransactionContext);

                    var listSubscriptionsByTopicResponse = await snsClient.ListSubscriptionsByTopicAsync(topicArn);

                    var subscriptions = listSubscriptionsByTopicResponse?.Subscriptions;

                    var subscription = subscriptions.FirstOrDefault(s => s.SubscriptionArn == sqsInfo.Arn);

                    if (subscription != null)
                    {
                        var unsubscribeResponse = await snsClient.UnsubscribeAsync(subscription.SubscriptionArn);

                        if (unsubscribeResponse.HttpStatusCode != HttpStatusCode.OK)
                        {
                            throw new SnsRebusException($"Error deleting subscription {subscriberAddress} on topic {topic}.", unsubscribeResponse.CreateAmazonExceptionFromResponse());
                        }
                    }
                }
            }
            m_log.Debug("Removed sqs subscriber {0} to sns topic {1}", subscriberAddress, topic);
        }
Beispiel #3
0
    public static async Task <TransportMessage> AwaitReceive(this ITransport transport, double timeoutSeconds = 5)
    {
        var stopwatch = Stopwatch.StartNew();
        var timeout   = TimeSpan.FromSeconds(timeoutSeconds);
        var source    = new CancellationTokenSource();

        while (stopwatch.Elapsed < timeout)
        {
            TransportMessage receivedTransportMessage;

            using (var scope = new RebusTransactionScope())
            {
                receivedTransportMessage = await transport.Receive(scope.TransactionContext, source.Token);

                await scope.CompleteAsync();
            }

            if (receivedTransportMessage != null)
            {
                return(receivedTransportMessage);
            }
        }

        throw new AssertionException($"Did not receive transport message from {transport} within {timeout} timeout");
    }
Beispiel #4
0
        public async Task PolymorphicMessageHandling_RemoveDuplicateHandlers()
        {
            // Arrange
            var services    = new ServiceCollection();
            var testHandler = new Message1Handler();

            // Act
            services
            .AddSingleton <IHandleMessages <Message1> >(testHandler)
            .AddSingleton <IHandleMessages <IMessage1> >(testHandler)
            .AddRebus(config => config
                      .Logging(l => l.None())
                      .Transport(t => t.UseInMemoryTransport(new InMemNetwork(false), "Messages"))
                      .Routing(r => r.TypeBased().MapAssemblyOf <Message1>("Messages")));

            var provider = services
                           .BuildServiceProvider()
                           .UseRebus();

            var activator = provider.GetRequiredService <IHandlerActivator>();

            // Assert
            using (var scope = new RebusTransactionScope())
            {
                var handlers = await activator.GetHandlers(new Message1(), scope.TransactionContext);

                handlers.Should().HaveCount(1);
            }
        }
Beispiel #5
0
    public static void UseRebusOutbox(this IApplicationBuilder app, string connectionString)
    {
        app.Use(async(context, next) =>
        {
            // if you've set up DI resolution to fetch the current connection/transaction from a unit of work, you can do something like this:
            //var serviceProvider = context.RequestServices;
            //var connection = serviceProvider.GetRequiredService<SqlConnection>();
            //var transaction = serviceProvider.GetRequiredService<SqlTransaction>();

            // but in this case we'll work with a simulated unit of work here:
            await using var connection = new SqlConnection(connectionString);
            await connection.OpenAsync();

            await using var transaction = connection.BeginTransaction();

            using var scope = new RebusTransactionScope();

            scope.UseOutbox(connection, transaction);

            // process the web request
            await next();

            // insert outgoing messages
            await scope.CompleteAsync();

            // commit!
            await transaction.CommitAsync();
        });
    }
Beispiel #6
0
        public async Task JustResolveManyTimes(int count)
        {
            var serviceCollection = new ServiceCollection();

            serviceCollection.AddTransient <IHandleMessages <string> >(p => new StringHandler());

            serviceCollection.AddSingleton(p => new DependencyInjectionHandlerActivator(p));

            using (var provider = serviceCollection.BuildServiceProvider())
            {
                var handlerActivator = provider.GetRequiredService <DependencyInjectionHandlerActivator>();

                var stopwatch = Stopwatch.StartNew();

                for (var counter = 0; counter < count; counter++)
                {
                    using (var scope = new RebusTransactionScope())
                    {
                        await handlerActivator.GetHandlers("this is my message", scope.TransactionContext);
                    }
                }

                var elapsedSeconds = stopwatch.Elapsed.TotalSeconds;

                Console.WriteLine($"{count} resolutions took {elapsedSeconds:0.0} s - that's {count/elapsedSeconds:0.0} /s");
            }
        }
    public async Task CheckIt()
    {
        var activator = Using(new BuiltinHandlerActivator());
        var network   = new InMemNetwork();
        var rolledBackMessageReceived = new ManualResetEvent(initialState: false);

        activator.Handle <ThisMessageShouldNotBeSent>(async _ => rolledBackMessageReceived.Set());

        activator.Handle <string>(async(bus, context, message) =>
        {
            using (var scope = new RebusTransactionScope())
            {
                await scope.CompleteAsync();
            }

            await bus.SendLocal(new ThisMessageShouldNotBeSent());

            throw new InvalidOperationException("OH NO!");
        });

        Configure.With(activator)
        .Transport(t => t.UseInMemoryTransport(network, "queue-name"))
        .Options(o => o.FailFastOn <InvalidOperationException>(when: exception => exception.Message.Contains("OH NO!")))
        .Start();

        await activator.Bus.SendLocal("HEJ MED DIG MIN VEN");

        Assert.That(rolledBackMessageReceived.WaitOne(TimeSpan.FromSeconds(3)), Is.False,
                    "Did not expect to receive the ThisMessageShouldNotBeSent, because its Rebus handler transaction was rolled back by an exception");
    }
Beispiel #8
0
    public void SendOperationsEnlistInTheSameTransactionContext(bool commitTransaction)
    {
        var receivedMessages = new ConcurrentQueue <string>();
        var bus = _activator.Bus.Advanced.SyncBus;

        _activator.AddHandlerWithBusTemporarilyStopped <string>(async msg => receivedMessages.Enqueue(msg));

        using (var context = new RebusTransactionScope())
        {
            bus.SendLocal("hej med dig min ven");
            bus.SendLocal("her er endnu en besked");

            if (commitTransaction)
            {
                context.Complete();
            }
        }

        Thread.Sleep(500);

        if (commitTransaction)
        {
            Assert.That(receivedMessages, Contains.Item("hej med dig min ven"));
            Assert.That(receivedMessages, Contains.Item("her er endnu en besked"));
        }
        else
        {
            Assert.That(receivedMessages.Count, Is.EqualTo(0));
        }
    }
Beispiel #9
0
        public async Task ItWorks()
        {
            var gotMessage = new ManualResetEvent(false);

            _activator.Handle <string>(async(bus, context, message) =>
            {
                Console.WriteLine($"Got message with ID {context.Headers.GetValue(Headers.MessageId)} - waiting 2 minutes....");
                await Task.Delay(TimeSpan.FromMinutes(2));
                Console.WriteLine("done waiting");

                gotMessage.Set();
            });

            _busStarter.Start();

            await _bus.SendLocal("hej med dig min ven!");

            gotMessage.WaitOrDie(TimeSpan.FromMinutes(2.1));

            // shut down bus
            _bus.Dispose();

            // see if queue is empty
            using var scope = new RebusTransactionScope();

            var message = await _transport.Receive(scope.TransactionContext, CancellationToken.None);

            await scope.CompleteAsync();

            if (message != null)
            {
                throw new AssertionException(
                          $"Did not expect to receive a message - got one with ID {message.Headers.GetValue(Headers.MessageId)}");
            }
        }
Beispiel #10
0
        public async Task ReceivesAlmostExpiredMessage()
        {
            var queueName = TestConfig.GetName("expiration");
            var transport = _factory.Create(queueName);
            var id        = Guid.NewGuid().ToString();

            using (var scope = new RebusTransactionScope())
            {
                var headers = new Dictionary <string, string>
                {
                    { Headers.MessageId, Guid.NewGuid().ToString() },
                    { "recognizzle", id },
                    { Headers.TimeToBeReceived, "00:00:20" },
                    { Headers.SentTime, DateTimeOffset.UtcNow.ToString("O") }//< expires after 10 seconds!
                };
                await transport.Send(queueName, MessageWith(headers), scope.TransactionContext);

                await scope.CompleteAsync();
            }

            await Task.Delay(3000);

            using (var scope = new RebusTransactionScope())
            {
                var transportMessage = await transport.Receive(scope.TransactionContext, _cancellationToken);

                await scope.CompleteAsync();

                Assert.That(transportMessage, Is.Not.Null);
            }
        }
Beispiel #11
0
        public async Task ReceivesNonExpiredMessage()
        {
            var queueName = TestConfig.GetName("expiration");
            var transport = _factory.Create(queueName);
            var id        = Guid.NewGuid().ToString();

            using (var scope = new RebusTransactionScope())
            {
                var headers = new Dictionary <string, string>
                {
                    { Headers.MessageId, Guid.NewGuid().ToString() },
                    { "recognizzle", id }
                };
                await transport.Send(queueName, MessageWith(headers), scope.TransactionContext);

                await scope.CompleteAsync();
            }

            await Task.Delay(5000);

            using (var scope = new RebusTransactionScope())
            {
                var transportMessage = await transport.Receive(scope.TransactionContext, _cancellationToken);

                await scope.CompleteAsync();

                Assert.That(transportMessage, Is.Not.Null);

                var headers = transportMessage.Headers;

                Assert.That(headers.ContainsKey("recognizzle"));
                Assert.That(headers["recognizzle"], Is.EqualTo(id));
            }
        }
Beispiel #12
0
        async Task <List <string> > GetAll(ITransport input)
        {
            var transportMessages = new List <string>();
            var receivedNulls     = 0;

            while (receivedNulls < 5)
            {
                using (var scope = new RebusTransactionScope())
                {
                    var msg = await input.Receive(scope.TransactionContext, _cancellationToken);

                    if (msg != null)
                    {
                        transportMessages.Add(GetStringBody(msg));
                        await scope.CompleteAsync();

                        continue;
                    }

                    await Task.Delay(100);

                    receivedNulls++;
                }
            }

            return(transportMessages);
        }
Beispiel #13
0
        public static async Task <TransportMessage> WaitForNextMessage(this ITransport transport, int timeoutSeconds = 5)
        {
            var stopwatch = Stopwatch.StartNew();

            while (true)
            {
                using (var scope = new RebusTransactionScope())
                {
                    var nextMessage = await transport.Receive(scope.TransactionContext, CancellationToken.None);

                    await scope.CompleteAsync();

                    if (nextMessage != null)
                    {
                        return(nextMessage);
                    }
                }

                await Task.Delay(100);

                if (stopwatch.Elapsed < TimeSpan.FromSeconds(timeoutSeconds))
                {
                    continue;
                }

                throw new TimeoutException($"Did not receive message from transport with address '{transport.Address}' within {timeoutSeconds} s timeout");
            }
        }
Beispiel #14
0
        static async Task PutInQueue(ITransport transport, TransportMessage transportMessage)
        {
            using var scope = new RebusTransactionScope();
            await transport.Send(QueueName, transportMessage, scope.TransactionContext);

            await scope.CompleteAsync();
        }
Beispiel #15
0
        public async Task Send_StoresMessagesToOutboxOnCommit()
        {
            using var rebusTransactionScope = new RebusTransactionScope();

            var          transportMessage1   = new TransportMessage(new Dictionary <string, string>(), new byte[0]);
            const string destinationAddress1 = "TestAddress1";
            var          transportMessage2   = new TransportMessage(new Dictionary <string, string>(), new byte[0]);
            const string destinationAddress2 = "TestAddress2";

            await _decorator.Send(destinationAddress1, transportMessage1, rebusTransactionScope.TransactionContext);

            await _decorator.Send(destinationAddress2, transportMessage2, rebusTransactionScope.TransactionContext);

            Assert.True(rebusTransactionScope.TransactionContext.Items.TryGetValue(
                            OutboxTransportDecorator.OutgoingMessagesItemsKey, out var outgoingMessagesObject));

            var outgoingMessages = ((IEnumerable <TransportMessage>)outgoingMessagesObject).ToArray();

            Assert.Contains(transportMessage1, outgoingMessages);
            Assert.Contains(transportMessage2, outgoingMessages);

            var recipient1 = Assert.Contains(OutboxHeaders.Recipient, transportMessage1.Headers as IDictionary <string, string>);

            Assert.Equal(destinationAddress1, recipient1);

            var recipient2 = Assert.Contains(OutboxHeaders.Recipient, transportMessage2.Headers as IDictionary <string, string>);

            Assert.Equal(destinationAddress2, recipient2);

            await rebusTransactionScope.CompleteAsync();

            await _outboxStorage.Received().Store(transportMessage1);

            await _outboxStorage.Received().Store(transportMessage2);
        }
Beispiel #16
0
        public void TakeTime(int count)
        {
            var activator = new BuiltinHandlerActivator();

            Using(activator);

            activator.Handle <string>(async str => { });
            activator.Handle <string>(async(bus, str) => { });
            activator.Handle <string>(async(bus, context, str) => { });

            var stopwatch = Stopwatch.StartNew();

            for (var counter = 0; counter < count; counter++)
            {
                using (var scope = new RebusTransactionScope())
                {
                    // ReSharper disable once UnusedVariable
                    var handlers = _activator.GetHandlers("hej med dig", scope.TransactionContext).Result;
                }
            }

            var elapsedSeconds = stopwatch.Elapsed.TotalSeconds;

            Console.WriteLine($"{count} resolutions took {elapsedSeconds:0.0} s - that's {count/elapsedSeconds:0.0} /s");
        }
        public async Task WrapsInvokersSoTheyCanRunInsideAnActivity()
        {
            var step = new IncomingDiagnosticsHandlerInvokerWrapper();

            var headers = new Dictionary <string, string>
            {
                { Headers.Type, "MyType" }
            };
            var transportMessage = new TransportMessage(headers, Array.Empty <byte>());
            var message          = new Message(headers, Array.Empty <byte>());

            var innerInvoker = new TestInvoker(() => { });

            var handlerInvokers = new HandlerInvokers(message, new[] { innerInvoker });

            var scope   = new RebusTransactionScope();
            var context = new IncomingStepContext(transportMessage, scope.TransactionContext);

            context.Save(handlerInvokers);

            var callbackWasInvoked = false;
            await step.Process(context, () =>
            {
                callbackWasInvoked = true;
                return(Task.CompletedTask);
            });

            Assert.That(callbackWasInvoked);

            var updatedInvokers = context.Load <HandlerInvokers>();

            Assert.That(updatedInvokers, Is.Not.SameAs(handlerInvokers));
            Assert.That(updatedInvokers, Has.Exactly(1).Items.And.All.TypeOf <HandlerInvokerWrapper>());
        }
Beispiel #18
0
        public async Task DoesNotReceiveExpiredMessage()
        {
            var queueName = TestConfig.GetName("expiration");
            var transport = _factory.Create(queueName);
            var id        = Guid.NewGuid().ToString();

            using (var scope = new RebusTransactionScope())
            {
                var headers = new Dictionary <string, string>
                {
                    { Headers.MessageId, Guid.NewGuid().ToString() },
                    { "recognizzle", id },
                    { Headers.TimeToBeReceived, "00:00:04" } //< expires after 4 seconds!
                };
                await transport.Send(queueName, MessageWith(headers), scope.TransactionContext);

                await scope.CompleteAsync();
            }

            const int millisecondsDelay = 7000;

            var stopwatch = Stopwatch.StartNew();
            await Task.Delay(millisecondsDelay);

            Console.WriteLine($"Delay of {millisecondsDelay} ms actually lasted {stopwatch.ElapsedMilliseconds:0} ms");

            using (var scope = new RebusTransactionScope())
            {
                var transportMessage = await transport.Receive(scope.TransactionContext, _cancellationToken);

                await scope.CompleteAsync();

                Assert.That(transportMessage, Is.Null);
            }
        }
        public async Task CannotReceiveSameMessageTwiceEvenWhenSnapahotIsolationIsOn()
        {
            const string sentText         = "HEJ MED DIG MIN VEN!!!!!11";
            var          transportMessage = new TransportMessage(new Dictionary <string, string>(), Encoding.UTF8.GetBytes(sentText));

            var transport1 = GetTransport(";MultipleActiveResultSets=True;" + SqlTestHelper.ConnectionString, IsolationLevel.Snapshot);
            var transport2 = GetTransport(SqlTestHelper.ConnectionString, IsolationLevel.Snapshot);

            using (var scope = new RebusTransactionScope())
            {
                await transport1.Send(_queueName, transportMessage, scope.TransactionContext);

                await scope.CompleteAsync();
            }

            using (var scope1 = new RebusTransactionScope())
                using (var scope2 = new RebusTransactionScope())
                {
                    var message1 = await transport1.Receive(scope1.TransactionContext, CancellationToken.None);

                    var message2 = await transport2.Receive(scope2.TransactionContext, CancellationToken.None);

                    Assert.That(message1, Is.Not.Null);
                    Assert.That(Encoding.UTF8.GetString(message1.Body), Is.EqualTo(sentText));

                    Assert.That(message2, Is.Null,
                                "Expected the second message to be null, because we should NOT be able to accidentally peek at the same message as another ongoing transaction");

                    await scope2.CompleteAsync();

                    await scope1.CompleteAsync();
                }
        }
        public static IEnumerable <TransportMessage> GetMessages(this SqlServerTransport transport)
        {
            var messages = new List <TransportMessage>();

            AsyncHelpers.RunSync(async() =>
            {
                while (true)
                {
                    using (var scope = new RebusTransactionScope())
                    {
                        var transportMessage = await transport.Receive(scope.TransactionContext, CancellationToken.None);
                        if (transportMessage == null)
                        {
                            break;
                        }

                        messages.Add(transportMessage);

                        await scope.CompleteAsync();
                    }
                }
            });

            return(messages);
        }
Beispiel #21
0
        static List <int> SendMessages(int messageCount)
        {
            var transport = new MsmqTransport(QueueName, new ConsoleLoggerFactory(true));

            MsmqUtil.EnsureQueueExists(MsmqUtil.GetPath(QueueName));

            var sendIds = new List <int>();

            Enumerable.Range(0, messageCount)
            .Select(id => new SomeMessage {
                Id = id
            })
            .ToList()
            .ForEach(msg =>
            {
                using (var scope = new RebusTransactionScope())
                {
                    transport.Send(QueueName, TransportMessageHelpers.FromString(JsonConvert.SerializeObject(msg)), scope.TransactionContext).Wait();

                    scope.Complete();

                    sendIds.Add(msg.Id);
                }
            });

            return(sendIds);
        }
        public async Task DoesNotHitTheLimit()
        {
            var queueName = TestConfig.GetName("payload-limit");

            Using(new QueueDeleter(queueName));

            var activator = Using(new BuiltinHandlerActivator());

            activator.Handle <MessageWithText>(async _ => { });

            var bus = Configure.With(activator)
                      .Logging(l => l.Console(LogLevel.Info))
                      .Transport(t => t.UseAzureServiceBus(AsbTestConfig.ConnectionString, queueName))
                      .Start();

            using (var scope = new RebusTransactionScope())
            {
                var strings = Enumerable.Range(0, 1000)
                              .Select(n => new MessageWithText($"message {n}"));

                await Task.WhenAll(strings.Select(str => bus.SendLocal(str)));

                await scope.CompleteAsync();
            }
        }
Beispiel #23
0
        public void WorksWithPrefetch(int prefetch, int numberOfMessages, int maxParallelism)
        {
            var activator = Using(new BuiltinHandlerActivator());
            var counter   = new SharedCounter(numberOfMessages);

            Using(counter);

            activator.Handle <string>(async str =>
            {
                counter.Decrement();
            });

            Console.WriteLine("Sending {0} messages", numberOfMessages);

            var transport = GetTransport();
            var tasks     = Enumerable.Range(0, numberOfMessages)
                            .Select(i => $"THIS IS MESSAGE # {i}")
                            .Select(async msg =>
            {
                using (var scope = new RebusTransactionScope())
                {
                    var headers          = DefaultHeaders();
                    var body             = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(msg));
                    var transportMessage = new TransportMessage(headers, body);

                    await transport.Send(_queueName, transportMessage, scope.TransactionContext);

                    await scope.CompleteAsync();
                }
            })
                            .ToArray();

            Task.WhenAll(tasks).Wait();

            Console.WriteLine("Receiving {0} messages", numberOfMessages);

            var stopwatch = Stopwatch.StartNew();

            Configure.With(activator)
            .Logging(l => l.Console(LogLevel.Info))
            .Transport(t =>
            {
                t.UseAzureServiceBus(AsbTestConfig.ConnectionString, _queueName)
                .EnablePrefetching(prefetch);
            })
            .Options(o =>
            {
                o.SetNumberOfWorkers(1);
                o.SetMaxParallelism(maxParallelism);
            })
            .Start();

            counter.WaitForResetEvent(timeoutSeconds: (int)(numberOfMessages * 0.1 + 3));

            var elapsedSeconds = stopwatch.Elapsed.TotalSeconds;

            Console.WriteLine("Receiving {0} messages took {1:0.0} s - that's {2:0.0} msg/s",
                              numberOfMessages, elapsedSeconds, numberOfMessages / elapsedSeconds);
        }
Beispiel #24
0
        public async Task LotsOfAsyncStuffGoingDown(int numberOfMessages)
        {
            var receivedMessages = 0L;
            var messageIds       = new ConcurrentDictionary <int, int>();

            Console.WriteLine("Sending {0} messages", numberOfMessages);

            await Task.WhenAll(Enumerable.Range(0, numberOfMessages)
                               .Select(async i =>
            {
                using (var scope = new RebusTransactionScope())
                {
                    await _transport.Send(QueueName, RecognizableMessage(i), scope.TransactionContext);
                    await scope.CompleteAsync();
                    messageIds[i] = 0;
                }
            }));

            Console.WriteLine("Receiving {0} messages", numberOfMessages);

            using (new Timer(_ => Console.WriteLine("Received: {0} msgs", receivedMessages), null, 0, 1000))
            {
                var stopwatch = Stopwatch.StartNew();

                while (Interlocked.Read(ref receivedMessages) < numberOfMessages && stopwatch.Elapsed < TimeSpan.FromMinutes(2))
                {
                    await Task.WhenAll(Enumerable.Range(0, 10).Select(async __ =>
                    {
                        using (var scope = new RebusTransactionScope())
                        {
                            var msg = await _transport.Receive(scope.TransactionContext, _cancellationToken);
                            await scope.CompleteAsync();

                            if (msg != null)
                            {
                                Interlocked.Increment(ref receivedMessages);
                                var id = int.Parse(msg.Headers["id"]);
                                messageIds.AddOrUpdate(id, 1, (_, existing) => existing + 1);
                            }
                        }
                    }));
                }

                await Task.Delay(3000);
            }

            Assert.That(messageIds.Keys.OrderBy(k => k).ToArray(), Is.EqualTo(Enumerable.Range(0, numberOfMessages).ToArray()));

            var kvpsDifferentThanOne = messageIds.Where(kvp => kvp.Value != 1).ToList();

            if (kvpsDifferentThanOne.Any())
            {
                Assert.Fail(@"Oh no! the following IDs were not received exactly once:

{0}",
                            string.Join(Environment.NewLine, kvpsDifferentThanOne.Select(kvp => $"   {kvp.Key}: {kvp.Value}")));
            }
        }
Beispiel #25
0
        private async Task ProcessOutboxMessages()
        {
            _log.Debug("Starting outbox messages processor");

            while (!_busDisposalCancellationToken.IsCancellationRequested)
            {
                try
                {
                    bool waitForMessages;
                    using (var transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                    {
                        var messages = await _outboxStorage.Retrieve(_busDisposalCancellationToken, _topMessagesToRetrieve);

                        if (messages.Length > 0)
                        {
                            using (var rebusTransactionScope = new RebusTransactionScope())
                            {
                                foreach (var message in messages)
                                {
                                    var destinationAddress = message.Headers[OutboxHeaders.Recipient];
                                    message.Headers.Remove(OutboxHeaders.Recipient);
                                    await _transport.Send(destinationAddress, message,
                                                          rebusTransactionScope.TransactionContext);
                                }
                                await rebusTransactionScope.CompleteAsync();
                            }
                            waitForMessages = false;
                        }
                        else
                        {
                            waitForMessages = true;
                        }

                        transactionScope.Complete();
                    }

                    if (waitForMessages)
                    {
                        await _backoffStrategy.WaitNoMessageAsync(_busDisposalCancellationToken);
                    }
                    else
                    {
                        _backoffStrategy.Reset();
                    }
                }
                catch (OperationCanceledException) when(_busDisposalCancellationToken.IsCancellationRequested)
                {
                    // we're shutting down
                }
                catch (Exception exception)
                {
                    _log.Error(exception, "Unhandled exception in outbox messages processor");
                    await _backoffStrategy.WaitErrorAsync(_busDisposalCancellationToken);
                }
            }

            _log.Debug("Outbox messages processor stopped");
        }
Beispiel #26
0
 public async Task RespectsSerializedAccessToUnderlyingConnectionEvenWhenCalledInParallel()
 {
     using (var scope = new RebusTransactionScope())
     {
         await Task.WhenAll(
             _transport.Send(QueueName, RecognizableMessage(), scope.TransactionContext),
             _transport.Send(QueueName, RecognizableMessage(), scope.TransactionContext));
     }
 }
        void Send(string destinationAddress, string message)
        {
            Console.WriteLine("Sending to {0}", destinationAddress);

            using (var scope = new RebusTransactionScope())
            {
                _transport.Send(destinationAddress, NewMessage(message), scope.TransactionContext).Wait();
                scope.Complete();
            }
        }
Beispiel #28
0
        public async Task Handlers_ShouldHandleSameCovariantType()
        {
            var activator = Setup(new CovariantGenericParentMessageHandler(), typeof(IHandleMessages <ICovariantGeneric <Parent> >));

            using (var scope = new RebusTransactionScope())
            {
                var handlers = await activator.GetHandlers(new ConcreteCovariantGeneric <Parent>(), scope.TransactionContext);

                handlers.Should().HaveCount(1);
            }
        }
Beispiel #29
0
        public async Task Handlers_ShouldNotHandleSupertype()
        {
            var activator = Setup(new ChildMessageHandler(), typeof(IHandleMessages <Child>));

            using (var scope = new RebusTransactionScope())
            {
                var handlers = await activator.GetHandlers(new Parent(), scope.TransactionContext);

                handlers.Should().HaveCount(0);
            }
        }
Beispiel #30
0
        public async Task Handlers_ShouldHandleIFailedMessages()
        {
            var activator = Setup(new FailedMessageHandler(), typeof(IHandleMessages <IFailed <object> >));

            using (var scope = new RebusTransactionScope())
            {
                var handlers = await activator.GetHandlers(new FailedMessage <Child>(), scope.TransactionContext);

                handlers.Should().HaveCount(1);
            }
        }