Ejemplo n.º 1
0
        public async Task DeferMessages(bool isSessionSpecified)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var messageCount = 10;
                var sessionId    = "sessionId1";
                IEnumerable <ServiceBusMessage> messages = GetMessages(messageCount, sessionId);
                await sender.SendBatchAsync(messages);

                var clientOptions = new ServiceBusReceiverClientOptions()
                {
                    SessionId       = isSessionSpecified ? sessionId : null,
                    IsSessionEntity = true,
                };
                var receiver             = new ServiceBusReceiverClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName, clientOptions);
                var receivedMessageCount = 0;
                var messageEnum          = messages.GetEnumerator();

                foreach (var item in await receiver.ReceiveBatchAsync(messageCount))
                {
                    receivedMessageCount++;
                    messageEnum.MoveNext();
                    Assert.AreEqual(item.MessageId, messageEnum.Current.MessageId);
                    Assert.AreEqual(item.SessionId, messageEnum.Current.SessionId);
                    await receiver.DeferAsync(item.SystemProperties.LockToken);
                }
                Assert.AreEqual(receivedMessageCount, messageCount);

                // TODO: Call ReceiveDeferredMessageAsync() to verify the messages
            }
        }
Ejemplo n.º 2
0
        public async Task CompleteMessages()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var messageCount = 10;
                IEnumerable <ServiceBusMessage> messages = GetMessages(messageCount);
                await sender.SendBatchAsync(messages);

                var receiver             = new ServiceBusReceiverClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var receivedMessageCount = 0;
                var messageEnum          = messages.GetEnumerator();

                foreach (var item in await receiver.ReceiveBatchAsync(messageCount))
                {
                    receivedMessageCount++;
                    messageEnum.MoveNext();
                    Assert.AreEqual(item.MessageId, messageEnum.Current.MessageId);
                    await receiver.CompleteAsync(item.SystemProperties.LockToken);
                }
                Assert.AreEqual(receivedMessageCount, messageCount);

                var message = receiver.PeekAsync();
                Assert.IsNull(message.Result);
            }
        }
Ejemplo n.º 3
0
        public async Task Peek()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var messageCt = 10;

                IEnumerable <ServiceBusMessage> sentMessages = GetMessages(messageCt);
                await sender.SendBatchAsync(sentMessages);

                await using var receiver = new ServiceBusReceiverClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);

                Dictionary <string, string> sentMessageIdToLabel = new Dictionary <string, string>();
                foreach (ServiceBusMessage message in sentMessages)
                {
                    sentMessageIdToLabel.Add(message.MessageId, Encoding.Default.GetString(message.Body));
                }

                var ct = 0;
                foreach (ServiceBusMessage peekedMessage in await receiver.PeekBatchAsync(
                             maxMessages: messageCt))
                {
                    var peekedText = Encoding.Default.GetString(peekedMessage.Body);
                    ct++;
                }
                Assert.AreEqual(messageCt, ct);
            }
        }
Ejemplo n.º 4
0
        public async Task ReceiveMessagesInReceiveAndDeleteMode()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var messageCount = 10;
                IEnumerable <ServiceBusMessage> messages = GetMessages(messageCount);
                await sender.SendBatchAsync(messages);

                var clientOptions = new ServiceBusReceiverClientOptions()
                {
                    ReceiveMode = ReceiveMode.ReceiveAndDelete,
                };
                var receiver             = new ServiceBusReceiverClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName, clientOptions);
                var receivedMessageCount = 0;
                var messageEnum          = messages.GetEnumerator();

                foreach (var item in await receiver.ReceiveBatchAsync(messageCount).ConfigureAwait(false))
                {
                    messageEnum.MoveNext();
                    Assert.AreEqual(item.MessageId, messageEnum.Current.MessageId);
                    receivedMessageCount++;
                }
                Assert.AreEqual(receivedMessageCount, messageCount);

                var message = receiver.PeekAsync();
                Assert.IsNull(message.Result);
            }
        }
Ejemplo n.º 5
0
        public async Task Peek_IncrementsSequenceNmber(int messageCt)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var sessionId = Guid.NewGuid().ToString();
                // send the messages
                IEnumerable <ServiceBusMessage> sentMessages = GetMessages(messageCt, sessionId);
                await sender.SendBatchAsync(sentMessages);

                var options = new ServiceBusReceiverClientOptions()
                {
                    SessionId       = sessionId,
                    IsSessionEntity = true
                };
                var receiver = new ServiceBusReceiverClient(
                    TestEnvironment.ServiceBusConnectionString,
                    scope.QueueName,
                    options);


                long seq = 0;
                for (int i = 0; i < messageCt; i++)
                {
                    ServiceBusMessage msg = await receiver.PeekAsync();

                    Assert.IsTrue(msg.SystemProperties.SequenceNumber > seq);
                    if (seq > 0)
                    {
                        Assert.IsTrue(msg.SystemProperties.SequenceNumber == seq + 1);
                    }
                    seq = msg.SystemProperties.SequenceNumber;
                }
            }
        }
Ejemplo n.º 6
0
        public async Task Receive_StopProcessing(int numThreads)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(
                             enablePartitioning: false,
                             enableSession: false))
            {
                await using var sender = new ServiceBusSenderClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName);
                int numMessages = 50;
                await sender.SendBatchAsync(GetMessages(numMessages));

                await using var processor = new ServiceBusProcessorClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName);
                int messageProcessedCt = 0;

                // stop processing halfway through
                int stopAfterMessagesCt = numMessages / 2;
                var options             = new ProcessingOptions()
                {
                    MaxConcurrentCalls = numThreads
                };

                TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);
                processor.ProcessMessageAsync += ProcessMessage;
                processor.ProcessErrorAsync   += ExceptionHandler;
                await processor.StartProcessingAsync(options);

                async Task ProcessMessage(ServiceBusMessage message, ServiceBusSession session)
                {
                    Interlocked.Increment(ref messageProcessedCt);
                    if (messageProcessedCt == stopAfterMessagesCt)
                    {
                        await processor.StopProcessingAsync();

                        tcs.TrySetResult(true);
                    }
                }

                await tcs.Task;
                var remainingCt = 0;
                var receiver    = new ServiceBusReceiverClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);

                foreach (ServiceBusMessage message in await receiver.ReceiveBatchAsync(numMessages))
                {
                    remainingCt++;
                }

                // can't assert on the exact amount processed due to threads that
                // are already in flight when calling StopProcessingAsync, but we can at least verify that there are remaining messages
                Assert.IsTrue(remainingCt > 0);
                Assert.IsTrue(messageProcessedCt < numMessages);
            }
        }
Ejemplo n.º 7
0
        public async Task DeadLetterMessages(bool isSessionSpecified)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var messageCount = 10;
                var sessionId    = "sessionId1";
                IEnumerable <ServiceBusMessage> messages = GetMessages(messageCount, sessionId);
                await sender.SendBatchAsync(messages);

                var clientOptions = new ServiceBusReceiverClientOptions()
                {
                    SessionId       = isSessionSpecified ? sessionId : null,
                    IsSessionEntity = true,
                };
                var receiver             = new ServiceBusReceiverClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName, clientOptions);
                var receivedMessageCount = 0;
                var messageEnum          = messages.GetEnumerator();

                foreach (var item in await receiver.ReceiveBatchAsync(messageCount))
                {
                    receivedMessageCount++;
                    messageEnum.MoveNext();
                    Assert.AreEqual(item.MessageId, messageEnum.Current.MessageId);
                    Assert.AreEqual(item.SessionId, messageEnum.Current.SessionId);
                    await receiver.DeadLetterAsync(item.SystemProperties.LockToken);
                }
                Assert.AreEqual(receivedMessageCount, messageCount);

                var message = receiver.PeekAsync();
                Assert.IsNull(message.Result);

                // TODO: System.InvalidOperationException : Cannot create a MessageSession for a sub-queue.

                // messageEnum.Reset();
                // receivedMessageCount = 0;
                // string deadLetterQueuePath = EntityNameFormatter.FormatDeadLetterPath(scope.QueueName);
                // var deadLetterReceiver = new ServiceBusReceiverClient(TestEnvironment.ServiceBusConnectionString, deadLetterQueuePath, sessionOptions);

                // foreach (var item in await deadLetterReceiver.ReceiveBatchAsync(messageCount))
                // {
                //    receivedMessageCount++;
                //    messageEnum.MoveNext();
                //    Assert.AreEqual(item.MessageId, messageEnum.Current.MessageId);
                //    Assert.AreEqual(item.SessionId, messageEnum.Current.SessionId);
                //    await deadLetterReceiver.CompleteAsync(item.SystemProperties.LockToken);
                // }
                // Assert.AreEqual(receivedMessageCount, messageCount);

                // var deadLetterMessage = deadLetterReceiver.PeekAsync();
                // Assert.IsNull(deadLetterMessage.Result);
            }
        }
Ejemplo n.º 8
0
        public async Task Peek_Session(long?sequenceNumber, string partitionKey)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var messageCt = 10;
                var sessionId = Guid.NewGuid().ToString();

                // send the messages
                IEnumerable <ServiceBusMessage> sentMessages = GetMessages(messageCt, sessionId, partitionKey);
                await sender.SendBatchAsync(sentMessages);

                Dictionary <string, ServiceBusMessage> sentMessageIdToMsg = new Dictionary <string, ServiceBusMessage>();
                foreach (ServiceBusMessage message in sentMessages)
                {
                    sentMessageIdToMsg.Add(message.MessageId, message);
                }

                var options = new ServiceBusReceiverClientOptions()
                {
                    SessionId       = sessionId,
                    IsSessionEntity = true
                };
                var receiver = new ServiceBusReceiverClient(
                    TestEnvironment.ServiceBusConnectionString,
                    scope.QueueName,
                    options);

                sequenceNumber ??= 1;

                // verify peeked == send
                var ct = 0;
                foreach (ServiceBusMessage peekedMessage in await receiver.PeekBatchBySequenceAsync(
                             fromSequenceNumber: (long)sequenceNumber,
                             maxMessages: messageCt))
                {
                    var peekedText = Encoding.Default.GetString(peekedMessage.Body);
                    var sentMsg    = sentMessageIdToMsg[peekedMessage.MessageId];

                    sentMessageIdToMsg.Remove(peekedMessage.MessageId);
                    Assert.AreEqual(Encoding.Default.GetString(sentMsg.Body), peekedText);
                    Assert.AreEqual(sentMsg.PartitionKey, peekedMessage.PartitionKey);
                    Assert.IsTrue(peekedMessage.SystemProperties.SequenceNumber >= sequenceNumber);
                    TestContext.Progress.WriteLine($"{peekedMessage.Label}: {peekedText}");
                    ct++;
                }
                if (sequenceNumber == 1)
                {
                    Assert.AreEqual(messageCt, ct);
                }
            }
        }
Ejemplo n.º 9
0
        public async Task Receive_Event(int numThreads)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(
                             enablePartitioning: false,
                             enableSession: false))
            {
                await using var sender = new ServiceBusSenderClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName);

                // use double the number of threads so we can make sure we test that we don't
                // retrieve more messages than expected when there are more messages available
                await sender.SendBatchAsync(GetMessages(numThreads * 2));

                await using var receiver = new ServiceBusReceiverClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName);
                int messageCt = 0;

                var options = new MessageHandlerOptions()
                {
                    MaxConcurrentCalls = numThreads
                };

                TaskCompletionSource <bool>[] completionSources = Enumerable
                                                                  .Range(0, numThreads)
                                                                  .Select(index => new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously))
                                                                  .ToArray();
                var completionSourceIndex = -1;

                receiver.ProcessMessageAsync += ProcessMessage;
                receiver.ProcessErrorAsync   += ExceptionHandler;
                await receiver.StartReceivingAsync(options);

                async Task ProcessMessage(ServiceBusMessage message)
                {
                    await receiver.CompleteAsync(message.SystemProperties.LockToken);

                    Interlocked.Increment(ref messageCt);
                    var setIndex = Interlocked.Increment(ref completionSourceIndex);

                    completionSources[setIndex].TrySetResult(true);
                }

                await Task.WhenAll(completionSources.Select(source => source.Task));

                // we complete each thread after one message being processed, so the total number of messages
                // processed should equal the number of threads
                Assert.AreEqual(numThreads, messageCt);
            }
        }
Ejemplo n.º 10
0
        public async Task RoundRobinSessions()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var messageCt             = 10;
                HashSet <string> sessions = new HashSet <string>()
                {
                    "1", "2", "3"
                };

                // send the messages
                foreach (string session in sessions)
                {
                    await sender.SendBatchAsync(GetMessages(messageCt, session));
                }

                // create receiver not scoped to a specific session
                for (int i = 0; i < 10; i++)
                {
                    var options = new ServiceBusReceiverClientOptions()
                    {
                        IsSessionEntity = true
                    };

                    var receiver = new ServiceBusReceiverClient(
                        TestEnvironment.ServiceBusConnectionString,
                        scope.QueueName,
                        options);

                    foreach (ServiceBusMessage peekedMessage in await receiver.PeekBatchBySequenceAsync(
                                 fromSequenceNumber: 1,
                                 maxMessages: 10))
                    {
                        var sessionId = await receiver.Session.GetSessionIdAsync();

                        Assert.AreEqual(sessionId, peekedMessage.SessionId);
                    }

                    // Close the receiver client when we are done with it. Since the sessionClient doesn't own the underlying connection, the connection remains open, but the session link will be closed.
                    await receiver.CloseAsync();
                }
            }
        }
Ejemplo n.º 11
0
        public async Task Schedule()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var scheduleTime = DateTimeOffset.UtcNow.AddHours(10);
                var sequenceNum  = await sender.ScheduleMessageAsync(GetMessage(), scheduleTime);

                await using var receiver = new ServiceBusReceiverClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                ServiceBusMessage msg = await receiver.PeekBySequenceAsync(sequenceNum);

                Assert.AreEqual(0, Convert.ToInt32(new TimeSpan(scheduleTime.Ticks - msg.ScheduledEnqueueTimeUtc.Ticks).TotalSeconds));

                await sender.CancelScheduledMessageAsync(sequenceNum);

                msg = await receiver.PeekBySequenceAsync(sequenceNum);

                Assert.IsNull(msg);
            }
        }
Ejemplo n.º 12
0
        public async Task PeekMultipleSessions_ShouldThrow()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var messageCt = 10;
                var sessionId = Guid.NewGuid().ToString();
                // send the messages
                IEnumerable <ServiceBusMessage> sentMessages = GetMessages(messageCt, sessionId);
                await sender.SendBatchAsync(sentMessages);

                var options = new ServiceBusReceiverClientOptions()
                {
                    SessionId       = sessionId,
                    IsSessionEntity = true
                };
                var receiver1 = new ServiceBusReceiverClient(
                    TestEnvironment.ServiceBusConnectionString,
                    scope.QueueName,
                    options);
                var receiver2 = new ServiceBusReceiverClient(
                    TestEnvironment.ServiceBusConnectionString,
                    scope.QueueName,
                    options);
                Dictionary <string, ServiceBusMessage> sentMessageIdToMsg = new Dictionary <string, ServiceBusMessage>();

                // peek the messages
                Assert.That(() => ScheduleTasksAsync(), Throws.Exception);

                async Task ScheduleTasksAsync()
                {
                    Task peek1 = receiver1.PeekBatchBySequenceAsync(
                        fromSequenceNumber: 1,
                        maxMessages: messageCt);
                    Task peek2 = receiver2.PeekBatchBySequenceAsync(
                        fromSequenceNumber: 1,
                        maxMessages: messageCt);
                    await Task.WhenAll(peek1, peek2);
                }
            }
        }
Ejemplo n.º 13
0
        public async Task ReceiveMessagesInPeekLockMode()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var messageCount = 10;
                var sessionId    = "sessionId1";
                IEnumerable <ServiceBusMessage> messages = GetMessages(messageCount, sessionId);
                await sender.SendBatchAsync(messages);

                ServiceBusConnection conn = new ServiceBusConnection(TestEnvironment.ServiceBusConnectionString, scope.QueueName);
                var options = new ServiceBusReceiverClientOptions()
                {
                    SessionId       = sessionId,
                    IsSessionEntity = true
                };
                var receiver             = new ServiceBusReceiverClient(TestEnvironment.ServiceBusConnectionString, scope.QueueName, options);
                var receivedMessageCount = 0;
                var messageEnum          = messages.GetEnumerator();

                foreach (var item in await receiver.ReceiveBatchAsync(messageCount))
                {
                    receivedMessageCount++;
                    messageEnum.MoveNext();
                    Assert.AreEqual(item.MessageId, messageEnum.Current.MessageId);
                    Assert.AreEqual(item.SessionId, messageEnum.Current.SessionId);
                    Assert.AreEqual(item.SystemProperties.DeliveryCount, 1);
                }
                Assert.AreEqual(receivedMessageCount, messageCount);

                messageEnum.Reset();
                foreach (var item in await receiver.PeekBatchAsync(messageCount))
                {
                    messageEnum.MoveNext();
                    Assert.AreEqual(item.SessionId, messageEnum.Current.SessionId);
                    Assert.AreEqual(item.MessageId, messageEnum.Current.MessageId);
                }
            }
        }
Ejemplo n.º 14
0
 /// <summary>
 ///   Initializes a new instance of the <see cref="ServiceBusProcessorClient"/> class.
 /// </summary>
 ///
 /// <param name="connection">The <see cref="ServiceBusConnection" /> connection to use for communication with the Service Bus service.</param>
 /// <param name="clientOptions">A set of options to apply when configuring the consumer.</param>
 ///
 public ServiceBusProcessorClient(
     ServiceBusConnection connection,
     ServiceBusProcessorClientOptions clientOptions = default)
 {
     _receiver = new ServiceBusReceiverClient(connection, clientOptions?.ToServiceBusReceiverClientOptions() ?? new ServiceBusReceiverClientOptions());
 }
Ejemplo n.º 15
0
        public async Task Receive_Event_SessionId(int numThreads)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(
                             enablePartitioning: false,
                             enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName);

                // send 1 message for each thread and use a different session for each message
                ConcurrentDictionary <string, bool> sessions = new ConcurrentDictionary <string, bool>();
                string sessionId = null;
                for (int i = 0; i < numThreads; i++)
                {
                    sessionId = Guid.NewGuid().ToString();
                    await sender.SendAsync(GetMessage(sessionId));

                    sessions.TryAdd(sessionId, true);
                }

                var clientOptions = new ServiceBusReceiverClientOptions()
                {
                    // just use the last sessionId from the loop above
                    SessionId       = sessionId,
                    IsSessionEntity = true,
                };

                await using var receiver = new ServiceBusReceiverClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName,
                                clientOptions);
                int messageCt = 0;

                var options = new MessageHandlerOptions()
                {
                    MaxConcurrentCalls = numThreads
                };

                TaskCompletionSource <bool>[] completionSources = Enumerable
                                                                  .Range(0, numThreads)
                                                                  .Select(index => new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously))
                                                                  .ToArray();
                var completionSourceIndex = -1;

                receiver.ProcessSessionMessageAsync += ProcessMessage;
                receiver.ProcessErrorAsync          += ExceptionHandler;
                await receiver.StartReceivingAsync(options);

                async Task ProcessMessage(ServiceBusMessage message, ServiceBusSession session)
                {
                    await receiver.CompleteAsync(message.SystemProperties.LockToken);

                    Interlocked.Increment(ref messageCt);
                    sessions.TryRemove(message.SessionId, out bool _);
                    Assert.AreEqual(sessionId, message.SessionId);
                    Assert.AreEqual(sessionId, await session.GetSessionIdAsync());
                    Assert.IsNotNull(await session.GetLockedUntilUtcAsync());
                    var setIndex = Interlocked.Increment(ref completionSourceIndex);

                    completionSources[setIndex].TrySetResult(true);
                }

                await Task.WhenAny(completionSources.Select(source => source.Task));

                // although we are allowing concurrent calls,
                // since we are specifying a specific session, the
                // concurrency won't really work as only one receiver can be linked to the session; TODO may want to add validation for this
                Assert.AreEqual(1, messageCt);

                // we should have received messages from only the specified session
                Assert.AreEqual(numThreads - 1, sessions.Count);
            }
        }
Ejemplo n.º 16
0
        public async Task Receive_Event_Consumes_All_Messages(int numThreads)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(
                             enablePartitioning: false,
                             enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName);

                // send 1 message for each thread and use a different session for each message
                ConcurrentDictionary <string, bool> sessions = new ConcurrentDictionary <string, bool>();
                for (int i = 0; i < numThreads; i++)
                {
                    var sessionId = Guid.NewGuid().ToString();
                    await sender.SendAsync(GetMessage(sessionId));

                    sessions.TryAdd(sessionId, true);
                }

                var clientOptions = new ServiceBusReceiverClientOptions()
                {
                    IsSessionEntity = true,
                    ReceiveMode     = ReceiveMode.ReceiveAndDelete,
                    RetryOptions    = new ServiceBusRetryOptions()
                    {
                        // to prevent the receive batch from taking a long time when we
                        // expect it to fail
                        MaximumRetries = 0,
                        TryTimeout     = TimeSpan.FromSeconds(5)
                    }
                };
                await using var receiver = new ServiceBusReceiverClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName,
                                clientOptions);
                int messageCt = 0;

                var options = new MessageHandlerOptions()
                {
                    MaxConcurrentCalls = numThreads
                };

                TaskCompletionSource <bool> taskCompletionSource = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

                receiver.ProcessSessionMessageAsync += ProcessMessage;
                receiver.ProcessErrorAsync          += ExceptionHandler;
                await receiver.StartReceivingAsync(options);

                async Task ProcessMessage(ServiceBusMessage message, ServiceBusSession session)
                {
                    await receiver.CompleteAsync(message.SystemProperties.LockToken);

                    sessions.TryRemove(message.SessionId, out bool _);
                    Assert.AreEqual(message.SessionId, await session.GetSessionIdAsync());
                    Assert.IsNotNull(await session.GetLockedUntilUtcAsync());
                    var ct = Interlocked.Increment(ref messageCt);

                    if (ct == numThreads)
                    {
                        taskCompletionSource.SetResult(true);
                    }
                }

                await taskCompletionSource.Task;


                // we only give each thread enough time to process one message, so the total number of messages
                // processed should equal the number of threads
                Assert.AreEqual(numThreads, messageCt);

                // we should have received messages from each of the sessions
                Assert.AreEqual(0, sessions.Count);

                // try receiving to verify empty
                // since all the messages are gone and we are using sessions, we won't actually
                // be able to open the Receive link
                Assert.That(async() => await receiver.ReceiveBatchAsync(numThreads), Throws.Exception);
            }
        }
Ejemplo n.º 17
0
        public async Task Receive_Event(int numThreads)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(
                             enablePartitioning: false,
                             enableSession: true))
            {
                await using var sender = new ServiceBusSenderClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName);

                // send 1 message for each thread and use a different session for each message
                ConcurrentDictionary <string, bool> sessions = new ConcurrentDictionary <string, bool>();
                for (int i = 0; i < numThreads; i++)
                {
                    var sessionId = Guid.NewGuid().ToString();
                    await sender.SendAsync(GetMessage(sessionId));

                    sessions.TryAdd(sessionId, true);
                }

                var clientOptions = new ServiceBusReceiverClientOptions()
                {
                    IsSessionEntity = true,
                    ReceiveMode     = ReceiveMode.ReceiveAndDelete
                };
                await using var receiver = new ServiceBusReceiverClient(
                                TestEnvironment.ServiceBusConnectionString,
                                scope.QueueName,
                                clientOptions);
                int messageCt = 0;

                var options = new MessageHandlerOptions()
                {
                    MaxConcurrentCalls = numThreads
                };

                TaskCompletionSource <bool>[] completionSources = Enumerable
                                                                  .Range(0, numThreads)
                                                                  .Select(index => new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously))
                                                                  .ToArray();

                var completionSourceIndex = -1;

                receiver.ProcessSessionMessageAsync += ProcessMessage;
                receiver.ProcessErrorAsync          += ExceptionHandler;
                await receiver.StartReceivingAsync(options);

                async Task ProcessMessage(ServiceBusMessage message, ServiceBusSession session)
                {
                    await receiver.CompleteAsync(message.SystemProperties.LockToken);

                    Interlocked.Increment(ref messageCt);
                    sessions.TryRemove(message.SessionId, out bool _);
                    Assert.AreEqual(message.SessionId, await session.GetSessionIdAsync());
                    Assert.IsNotNull(await session.GetLockedUntilUtcAsync());
                    var setIndex = Interlocked.Increment(ref completionSourceIndex);

                    completionSources[setIndex].TrySetResult(true);
                }

                await Task.WhenAll(completionSources.Select(source => source.Task));

                // we only give each thread enough time to process one message, so the total number of messages
                // processed should equal the number of threads
                Assert.AreEqual(numThreads, messageCt);

                // we should have received messages from each of the sessions
                Assert.AreEqual(0, sessions.Count);
            }
        }