예제 #1
0
        static async Task ReceiveSessionMessageAsync()
        {
            Console.WriteLine("=========================================================");
            Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
            Console.WriteLine("=========================================================");
            var options = new ServiceBusSessionProcessorOptions {
                AutoCompleteMessages         = false,
                MaxConcurrentSessions        = 2,
                MaxConcurrentCallsPerSession = 2
            };

            await using ServiceBusSessionProcessor processor = string.IsNullOrWhiteSpace(SubscriptionName) ?
                                                               srv.CreateSessionProcessor(QueueOrTopicName, options) :
                                                               srv.CreateSessionProcessor(QueueOrTopicName, SubscriptionName, options);
            processor.ProcessMessageAsync += async(arg) => {
                Console.WriteLine($"Received message: {arg.SessionId} SequenceNumber: {arg.Message.SequenceNumber} Body: {Encoding.UTF8.GetString(arg.Message.Body)}");
                if (AbandonarMultiplosDe > 0 && arg.Message.SequenceNumber % AbandonarMultiplosDe == 0)
                {
                    await arg.AbandonMessageAsync(arg.Message);
                }
                else
                {
                    await arg.CompleteMessageAsync(arg.Message);
                }
            };
            processor.ProcessErrorAsync += ExceptionReceivedHandler;
            await processor.StartProcessingAsync();

            Console.Read();
            Console.WriteLine("Exit ...");
            await processor.CloseAsync();
        }
        public void ProcessorOptionsSetOnClient()
        {
            var account = Encoding.Default.GetString(GetRandomBuffer(12));
            var fullyQualifiedNamespace = new UriBuilder($"{account}.servicebus.windows.net/").Host;
            var connString = $"Endpoint=sb://{fullyQualifiedNamespace};SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey={Encoding.Default.GetString(GetRandomBuffer(64))}";
            var client     = new ServiceBusClient(connString);
            var options    = new ServiceBusSessionProcessorOptions
            {
                AutoComplete                 = false,
                MaxConcurrentSessions        = 10,
                PrefetchCount                = 5,
                ReceiveMode                  = ReceiveMode.ReceiveAndDelete,
                MaxAutoLockRenewalDuration   = TimeSpan.FromSeconds(60),
                MaxConcurrentCallsPerSession = 4
            };
            var processor = client.CreateSessionProcessor("queueName", options);

            Assert.AreEqual(options.AutoComplete, processor.AutoComplete);
            Assert.AreEqual(options.MaxConcurrentSessions, processor.MaxConcurrentSessions);
            Assert.AreEqual(options.MaxConcurrentCallsPerSession, processor.MaxConcurrentCallsPerSession);
            Assert.AreEqual(options.PrefetchCount, processor.PrefetchCount);
            Assert.AreEqual(options.ReceiveMode, processor.ReceiveMode);
            Assert.AreEqual(options.MaxAutoLockRenewalDuration, processor.MaxAutoLockRenewalDuration);
            Assert.AreEqual(fullyQualifiedNamespace, processor.FullyQualifiedNamespace);
        }
예제 #3
0
        public async Task PluginsCanAlterMessageUsingSessionProcessor()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(
                             enablePartitioning: false,
                             enableSession: true))
            {
                var plugin  = new SendReceivePlugin();
                var options = new ServiceBusClientOptions();
                options.AddPlugin(plugin);
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString, options);
                var sender = client.CreateSender(scope.QueueName);

                await sender.SendMessageAsync(GetMessage("sessionId"));

                Assert.True(plugin.WasCalled);
                var processor = client.CreateSessionProcessor(scope.QueueName, new ServiceBusSessionProcessorOptions
                {
                    MaxConcurrentSessions = 1
                });
                processor.ProcessErrorAsync += ExceptionHandler;
                var tcs = new TaskCompletionSource <bool>();
                processor.ProcessMessageAsync += args =>
                {
                    Assert.AreEqual("received", args.Message.Body.ToString());
                    tcs.SetResult(true);
                    return(Task.CompletedTask);
                };
                await processor.StartProcessingAsync();

                await tcs.Task;
                await processor.StopProcessingAsync();
            }
        }
        public async Task SessionProcessorActivities()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                using var listener = new TestDiagnosticListener(EntityScopeFactory.DiagnosticNamespace);
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);
                var messageCt           = 2;
                var msgs = GetMessages(messageCt, "sessionId");
                await sender.SendMessagesAsync(msgs);

                Activity[] sendActivities = AssertSendActivities(false, sender, msgs, listener);

                ServiceBusSessionProcessor processor = client.CreateSessionProcessor(scope.QueueName,
                                                                                     new ServiceBusSessionProcessorOptions
                {
                    AutoComplete          = false,
                    MaxReceiveWaitTime    = TimeSpan.FromSeconds(10),
                    MaxConcurrentSessions = 1
                });
                TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>();
                int processedMsgCt = 0;
                processor.ProcessMessageAsync += args =>
                {
                    processedMsgCt++;
                    if (processedMsgCt == messageCt)
                    {
                        tcs.SetResult(true);
                    }
                    return(Task.CompletedTask);
                };
                processor.ProcessErrorAsync += ExceptionHandler;
                await processor.StartProcessingAsync();

                await tcs.Task;
                await processor.StopProcessingAsync();

                for (int i = 0; i < messageCt; i++)
                {
                    (string Key, object Value, DiagnosticListener)receiveStart = listener.Events.Dequeue();
                    (string Key, object Value, DiagnosticListener)receiveStop  = listener.Events.Dequeue();
                    (string Key, object Value, DiagnosticListener)processStart = listener.Events.Dequeue();
                    Assert.AreEqual(DiagnosticProperty.ProcessSessionMessageActivityName + ".Start", processStart.Key);
                    Activity processActivity = (Activity)processStart.Value;
                    AssertCommonTags(processActivity, processor.EntityPath, processor.FullyQualifiedNamespace);
                    CollectionAssert.Contains(
                        processActivity.Tags,
                        new KeyValuePair <string, string>(
                            DiagnosticProperty.MessageIdAttribute,
                            msgs[i].MessageId));
                    CollectionAssert.Contains(
                        processActivity.Tags,
                        new KeyValuePair <string, string>(
                            DiagnosticProperty.SessionIdAttribute,
                            msgs[i].SessionId));
                    (string Key, object Value, DiagnosticListener)processStop = listener.Events.Dequeue();
                    Assert.AreEqual(DiagnosticProperty.ProcessSessionMessageActivityName + ".Stop", processStop.Key);
                }
            };
        }
        private async Task RunSessionServiceProcessorAsync()
        {
            var  cred         = new DefaultAzureCredential();
            var  client       = new ServiceBusClient(NamespaceName, cred);
            long messageCount = 0;
            var  sw           = Stopwatch.StartNew();
            var  bagStart     = sw.ElapsedMilliseconds;

            Console.WriteLine($"Receiving from entity '{EntityName}' in namespace '{NamespaceName}'");

            var timer = new Timer(state =>
            {
                var snapshot    = Interlocked.Exchange(ref messageCount, 0);
                var bagDuration = sw.ElapsedMilliseconds - bagStart;
                bagStart        = sw.ElapsedMilliseconds;

                Console.ResetColor();
                Console.WriteLine($"\nReceived {snapshot / (bagDuration / 1000.0)} msg/sec,  {snapshot} in {bagDuration} ms");
            }, null, 10000, 10000);

            var options = new ServiceBusSessionProcessorOptions()
            {
                AutoCompleteMessages         = true,
                MaxConcurrentSessions        = 1,
                MaxConcurrentCallsPerSession = this.ConcurrentCalls,
                ReceiveMode   = this.ReceiveDelete ? ServiceBusReceiveMode.ReceiveAndDelete : ServiceBusReceiveMode.PeekLock,
                PrefetchCount = this.PrefetchCount,
                MaxAutoLockRenewalDuration = TimeSpan.FromMinutes(2),
                SessionIdleTimeout         = TimeSpan.FromSeconds(1)
            };

            var processor = client.CreateSessionProcessor(EntityName, options);

            processor.ProcessMessageAsync += async args =>
            {
                if (!string.IsNullOrEmpty(args.Message.SessionId) ||
                    !string.IsNullOrEmpty(args.Message.Subject))
                {
                    int color = Math.Abs(string.IsNullOrEmpty(args.Message.SessionId) ? args.Message.Subject.GetHashCode() : args.Message.SessionId.GetHashCode());
                    Console.BackgroundColor = ConsoleColor.Black;
                    Console.ForegroundColor = (ConsoleColor)((color % 14) + 1);
                }
                Console.Write($"[]");
                Interlocked.Increment(ref messageCount);
            };
            processor.ProcessErrorAsync += async args =>
            {
            };
            await processor.StartProcessingAsync();

            Console.ReadKey();

            timer.Dispose();
            await processor.StopProcessingAsync();
        }
예제 #6
0
            protected internal override SessionMessageProcessor CreateSessionMessageProcessor(
                ServiceBusClient client,
                string entityPath,
                ServiceBusSessionProcessorOptions options)
            {
                ServiceBusSessionProcessor processor;

                // override the options computed from ServiceBusOptions
                options.SessionIdleTimeout    = TimeSpan.FromSeconds(90);
                options.MaxConcurrentSessions = 1;
                if (entityPath == _firstQueueScope.QueueName)
                {
                    processor = client.CreateSessionProcessor(entityPath, options);
                }
                else
                {
                    string[] arr = entityPath.Split('/');
                    processor = client.CreateSessionProcessor(arr[0], arr[2], options);
                }

                processor.ProcessErrorAsync += args => Task.CompletedTask;
                return(new CustomSessionMessageProcessor(processor, _logger));
            }
예제 #7
0
        private static async Task SendRequestMessageWithResponse()
        {
            const string requestQueue  = "sbq-request-queue";
            const string responseQueue = "sbq-response-queue";

            var managementClient = new ServiceBusAdministrationClient(Config.Namespace, Config.Credential);

            if (!await managementClient.QueueExistsAsync(requestQueue))
            {
                await managementClient.CreateQueueAsync(requestQueue);
            }

            if (!await managementClient.QueueExistsAsync(responseQueue))
            {
                var createQueueOptions = new CreateQueueOptions(responseQueue)
                {
                    RequiresSession = true
                };

                await managementClient.CreateQueueAsync(createQueueOptions);
            }

            var responseSessionId = Guid.NewGuid().ToString();

            await using var requestClient = new ServiceBusClient(Config.Namespace, Config.Credential);

            var sender = requestClient.CreateSender(requestQueue);

            var message = new ServiceBusMessage(Encoding.UTF8.GetBytes("This is a simple test message"))
            {
                ReplyToSessionId = responseSessionId
            };

            Console.WriteLine("Press any key to send a message. Press Enter to exit.");

            await using var responseClient = new ServiceBusClient(Config.Namespace, Config.Credential);

            var serviceBusSessionProcessorOptions = new ServiceBusSessionProcessorOptions();

            serviceBusSessionProcessorOptions.SessionIds.Add(responseSessionId);

            var sessionProcessor = responseClient.CreateSessionProcessor(responseQueue, serviceBusSessionProcessorOptions);

            sessionProcessor.ProcessMessageAsync += MessageHandler;
            sessionProcessor.ProcessErrorAsync   += ErrorHandler;
예제 #8
0
        public async Task OnSessionExceptionHandlerCalledWhenRegisteredOnNonSessionfulQueue()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                var exceptionReceivedHandlerCalled = false;
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);

                var processor = client.CreateSessionProcessor(scope.QueueName);
                processor.ProcessMessageAsync += MessageHandler;
                processor.ProcessErrorAsync   += ErrorHandler;

                Task MessageHandler(ProcessSessionMessageEventArgs args)
                {
                    return(Task.CompletedTask);
                }

                Task ErrorHandler(ProcessErrorEventArgs args)
                {
                    Assert.NotNull(args);
                    Assert.NotNull(args.Exception);
                    if (args.Exception is InvalidOperationException)
                    {
                        exceptionReceivedHandlerCalled = true;
                    }
                    return(Task.CompletedTask);
                }

                await processor.StartProcessingAsync();

                var stopwatch = Stopwatch.StartNew();
                while (stopwatch.Elapsed.TotalSeconds <= 10)
                {
                    if (exceptionReceivedHandlerCalled)
                    {
                        break;
                    }

                    await Task.Delay(TimeSpan.FromSeconds(1));
                }

                Assert.True(exceptionReceivedHandlerCalled);
            }
        }
예제 #9
0
        public static async Task RunSessionProcessor(string connectionString, string queueName, TimeSpan timeSpan)
        {
            // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
            await using var client = new ServiceBusClient(connectionString);

            // get the options to use for configuring the processor
            var options = new ServiceBusSessionProcessorOptions
            {
                // By default after the message handler returns, the processor will complete the message
                // If I want more fine-grained control over settlement, I can set this to false.
                AutoCompleteMessages = false,

                // I can also allow for processing multiple sessions
                MaxConcurrentSessions = 5,

                // By default, there will be a single concurrent call per session. I can
                // increase that here to enable parallel processing within each session.
                MaxConcurrentCallsPerSession = 2
            };

            // create a processor that we can use to process the messages
            ServiceBusSessionProcessor processor = client.CreateSessionProcessor(queueName, options);

            processor.ProcessMessageAsync += MessageHandler;
            processor.ProcessErrorAsync   += ErrorHandler;

            await processor.StartProcessingAsync();

            // since the message handler will run in a background thread, in order to prevent
            // this sample from terminating immediately
            DateTime endProcessing = DateTime.Now.Add(timeSpan);

            while (DateTime.Now < endProcessing)
            {
                await Task.Delay(100);
            }

            // stop processing once the task completion source was completed.
            await processor.StopProcessingAsync();
        }
예제 #10
0
        public void ConcurrencyUpdateManager_Sessions_UpdatesProcessorConcurrency()
        {
            var concurrencyOptions = new OptionsWrapper <ConcurrencyOptions>(new ConcurrencyOptions {
                DynamicConcurrencyEnabled = true
            });
            var concurrencyManager = new ConcurrencyManager(concurrencyOptions, _loggerFactory, _mockConcurrencyThrottleManager.Object);

            _mockConcurrencyThrottleManager.Setup(p => p.GetStatus()).Returns(new ConcurrencyThrottleAggregateStatus {
                State = ThrottleState.Disabled
            });
            ServiceBusSessionProcessor sessionProcessor = _client.CreateSessionProcessor(_entityPath, new ServiceBusSessionProcessorOptions {
                MaxConcurrentSessions = 1, MaxConcurrentCallsPerSession = 1
            });
            Lazy <SessionMessageProcessor> sessionMessageProcessor = new Lazy <SessionMessageProcessor>(() => new SessionMessageProcessor(sessionProcessor));
            ILogger logger = _loggerFactory.CreateLogger("test");

            ServiceBusListener.ConcurrencyUpdateManager concurrencyUpdateManager = new ServiceBusListener.ConcurrencyUpdateManager(concurrencyManager, null, sessionMessageProcessor, true, _functionId, logger);

            // when no messages are being processed, concurrency is not adjusted
            Assert.AreEqual(1, sessionProcessor.MaxConcurrentSessions);
            Assert.AreEqual(1, sessionProcessor.MaxConcurrentCallsPerSession);
            SetFunctionCurrentConcurrency(concurrencyManager, _functionId, 10);
            concurrencyUpdateManager.UpdateConcurrency();
            Assert.AreEqual(1, sessionProcessor.MaxConcurrentSessions);
            Assert.AreEqual(1, sessionProcessor.MaxConcurrentCallsPerSession);

            // ensure processor concurrency is adjusted up
            concurrencyUpdateManager.MessageProcessed();
            concurrencyUpdateManager.UpdateConcurrency();
            Assert.AreEqual(10, sessionProcessor.MaxConcurrentSessions);
            Assert.AreEqual(1, sessionProcessor.MaxConcurrentCallsPerSession);

            // ensure processor concurrency is adjusted down
            SetFunctionCurrentConcurrency(concurrencyManager, _functionId, 5);
            concurrencyUpdateManager.MessageProcessed();
            concurrencyUpdateManager.UpdateConcurrency();
            Assert.AreEqual(5, sessionProcessor.MaxConcurrentSessions);
            Assert.AreEqual(1, sessionProcessor.MaxConcurrentCallsPerSession);
        }
        public async Task SessionProcessorActivities()
        {
            ClientDiagnosticListener.ProducedLink[] messageActivities = null;
            int  messageProcessedCt = 0;
            bool callbackExecuted   = false;

            _listener = new ClientDiagnosticListener(
                EntityScopeFactory.DiagnosticNamespace,
                scopeStartCallback: scope =>
            {
                if (scope.Name == DiagnosticProperty.ProcessSessionMessageActivityName)
                {
                    Assert.IsNotNull(messageActivities);
                    Assert.AreEqual(
                        messageActivities[messageProcessedCt],
                        scope.Links.Single());
                    callbackExecuted = true;
                }
            });
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);
                var messageCt           = 2;
                var msgs = ServiceBusTestUtilities.GetMessages(messageCt, "sessionId");
                await sender.SendMessagesAsync(msgs);

                Activity[] sendActivities = AssertSendActivities(false, sender, msgs);
                messageActivities = sendActivities.Select(a => new ClientDiagnosticListener.ProducedLink(a.ParentId, a.TraceStateString)).ToArray();

                ServiceBusSessionProcessor processor = client.CreateSessionProcessor(scope.QueueName,
                                                                                     new ServiceBusSessionProcessorOptions
                {
                    AutoCompleteMessages  = false,
                    SessionIdleTimeout    = TimeSpan.FromSeconds(10),
                    MaxConcurrentSessions = 1
                });
                TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>();
                processor.ProcessMessageAsync += args =>
                {
                    if (++messageProcessedCt == messageCt)
                    {
                        tcs.SetResult(true);
                    }
                    return(Task.CompletedTask);
                };
                processor.ProcessErrorAsync += ServiceBusTestUtilities.ExceptionHandler;
                await processor.StartProcessingAsync();

                await tcs.Task;
                await processor.StopProcessingAsync();

                for (int i = 0; i < messageCt; i++)
                {
                    _listener.AssertAndRemoveScope(DiagnosticProperty.ReceiveActivityName);
                    var processScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ProcessSessionMessageActivityName);
                    AssertCommonTags(processScope.Activity, processor.EntityPath, processor.FullyQualifiedNamespace);
                }
                Assert.IsTrue(callbackExecuted);
            }
        }
예제 #12
0
        public async Task Capture_Transaction_When_ProcessSessionMessage_From_Queue()
        {
            await using var scope = await QueueScope.CreateWithQueue(_adminClient, new CreateQueueOptions (Guid.NewGuid().ToString("D"))
            {
                RequiresSession = true
            });

            var sender = _client.CreateSender(scope.QueueName);

            await using var processor = _client.CreateSessionProcessor(scope.QueueName);

            processor.ProcessMessageAsync += args =>
            {
                _agent.Tracer.CurrentTransaction.CaptureSpan("ProcessSessionMessage", "process", s =>
                {
                    s.SetLabel("message", args.Message.ToString());
                });
                return(Task.CompletedTask);
            };

            processor.ProcessErrorAsync += args =>
            {
                _agent.Tracer.CurrentTransaction.CaptureException(args.Exception);
                return(Task.CompletedTask);
            };

            var messageCount = 3;
            var messages     = Enumerable.Range(1, messageCount)
                               .Select(i => new ServiceBusMessage($"test message {i}")
            {
                SessionId = "test"
            });

            await sender.SendMessagesAsync(messages).ConfigureAwait(false);

            await processor.StartProcessingAsync().ConfigureAwait(false);

            if (!_sender.WaitForTransactions(TimeSpan.FromMinutes(2), count: messageCount * 2))
            {
                throw new Exception($"{messageCount * 2} transactions not received in timeout");
            }

            var transactions = _sender.Transactions;

            transactions.Should().HaveCount(messageCount * 2);
            transactions
            .Count(t => t.Name == $"{ServiceBus.SegmentName} RECEIVE from {scope.QueueName}")
            .Should().Be(messageCount);

            var processTransactions = transactions
                                      .Where(t => t.Name == $"{ServiceBus.SegmentName} PROCESS from {scope.QueueName}")
                                      .ToList();

            processTransactions.Should().HaveCount(messageCount);

            foreach (var transaction in processTransactions)
            {
                var spans = _sender.Spans.Where(s => s.TransactionId == transaction.Id).ToList();
                spans.Should().HaveCount(1);
            }

            await processor.StopProcessingAsync();
        }
예제 #13
0
        private static async Task Main(string[] args)
        {
            await Prepare.Stage(connectionString, destination);

            await using var serviceBusClient = new ServiceBusClient(connectionString, new ServiceBusClientOptions
            {
                RetryOptions = new ServiceBusRetryOptions
                {
                    TryTimeout = TimeSpan.FromSeconds(2)
                }
            });
            await using var sender = serviceBusClient.CreateSender(destination);

            var messages = new List <ServiceBusMessage>
            {
                new ServiceBusMessage("Orange 1")
                {
                    SessionId = "Orange"
                },
                new ServiceBusMessage("Green 1")
                {
                    SessionId = "Green"
                },
                new ServiceBusMessage("Blue 1")
                {
                    SessionId = "Blue"
                },
                new ServiceBusMessage("Green 2")
                {
                    SessionId = "Green"
                },
                new ServiceBusMessage("Orange 2")
                {
                    SessionId = "Orange"
                },
                new ServiceBusMessage("Blue 2")
                {
                    SessionId = "Blue"
                },
                new ServiceBusMessage("Green 3")
                {
                    SessionId = "Green"
                },
                new ServiceBusMessage("Orange 3")
                {
                    SessionId = "Orange"
                },
                new ServiceBusMessage("Green 4")
                {
                    SessionId = "Green"
                },
                new ServiceBusMessage("Purple 1")
                {
                    SessionId = "Purple"
                },
                new ServiceBusMessage("Blue 3")
                {
                    SessionId = "Blue"
                },
                new ServiceBusMessage("Orange 4")
                {
                    SessionId = "Orange"
                }
            };

            await sender.SendMessagesAsync(messages);

            Console.WriteLine("Messages sent");

            await using var receiver = serviceBusClient.CreateSessionProcessor(destination, new ServiceBusSessionProcessorOptions
            {
                AutoCompleteMessages       = true,
                MaxConcurrentSessions      = 1,
                MaxAutoLockRenewalDuration = TimeSpan.FromMinutes(10),
                SessionIdleTimeout         = TimeSpan.FromSeconds(2)
            });
            receiver.ProcessMessageAsync += async processMessageEventArgs =>
            {
                var message = processMessageEventArgs.Message;

                await Console.Error.WriteLineAsync(
                    $"Received message on session '{processMessageEventArgs.SessionId}' with '{message.MessageId}' and content '{Encoding.UTF8.GetString(message.Body)}'");
            };
            receiver.ProcessErrorAsync += async processErrorEventArgs =>
            {
                await Console.Error.WriteLineAsync($"Exception: {processErrorEventArgs.Exception}");

                await Console.Error.WriteLineAsync($"FullyQualifiedNamespace: {processErrorEventArgs.FullyQualifiedNamespace}");

                await Console.Error.WriteLineAsync($"ErrorSource: {processErrorEventArgs.ErrorSource}");

                await Console.Error.WriteLineAsync($"EntityPath: {processErrorEventArgs.EntityPath}");
            };

            await receiver.StartProcessingAsync();

            Console.ReadLine();

            await receiver.StopProcessingAsync();
        }
예제 #14
0
        public ServiceBusSubscriberProcessor(ServiceBusClient client,
                                             string queueOrTopicName,
                                             string subscriptionName = default,
                                             ServiceBusSubscriberReceiveOptions options = default)
        {
            QueueOrTopicName = queueOrTopicName;
            SubscriptionName = subscriptionName;
            ServiceBusSubscriberReceiveOptions = options ?? new ServiceBusSubscriberReceiveOptions();

            var(sessionId, _, connectToDeadLetterQueue) = (options?.SessionId, ServiceBusSubscriberReceiveMessageTypes.Payload, options?.ConnectToDeadLetterQueue ?? false);

            if (string.IsNullOrWhiteSpace(subscriptionName))
            {
                if (string.IsNullOrWhiteSpace(sessionId))
                {
                    _serviceBusProcessorAsObject = client.CreateProcessor(
                        queueOrTopicName,
                        new ServiceBusProcessorOptions
                    {
                        AutoCompleteMessages = false,
                        SubQueue             = connectToDeadLetterQueue ? SubQueue.DeadLetter : SubQueue.None
                    });

                    return;
                }

                _serviceBusProcessorAsObject = client.CreateSessionProcessor(
                    queueOrTopicName,
                    new ServiceBusSessionProcessorOptions
                {
                    AutoCompleteMessages         = false,
                    MaxConcurrentSessions        = 5,
                    MaxConcurrentCallsPerSession = 2,
                    SessionIds = { sessionId }
                });

                return;
            }

            if (string.IsNullOrWhiteSpace(sessionId))
            {
                _serviceBusProcessorAsObject = client.CreateProcessor(
                    queueOrTopicName,
                    subscriptionName,
                    new ServiceBusProcessorOptions
                {
                    AutoCompleteMessages = false,
                    SubQueue             = connectToDeadLetterQueue ? SubQueue.DeadLetter : SubQueue.None
                });

                return;
            }

            _serviceBusProcessorAsObject = client.CreateSessionProcessor(
                queueOrTopicName,
                subscriptionName,
                new ServiceBusSessionProcessorOptions
            {
                AutoCompleteMessages         = false,
                MaxConcurrentSessions        = 5,
                MaxConcurrentCallsPerSession = 2,
                SessionIds = { sessionId }
            });
        }
예제 #15
0
        public async Task ReceiveWithSession(Func <MessageArgs, CancellationToken, Task <bool> > received, MessageSessionOptions options = null, CancellationToken cancellationToken = default)
        {
            if (options == null)
            {
                options = new MessageSessionOptions
                {
                    MaxConcurrentCallsPerSession = 1,
                    MaxConcurrentSessions        = 1,
                    SessionIdleTimeout           = TimeSpan.FromSeconds(2),
                    MaxAutoLockRenewalDuration   = TimeSpan.FromHours(24),
                    AutoCompleteMessages         = false,
                    ReceiveAndDelete             = false,
                };
            }

            if (client.IsClosed)
            {
                Init(connectionString, queueName);
            }

            var processor = client.CreateSessionProcessor(queueName, new ServiceBusSessionProcessorOptions
            {
                AutoCompleteMessages         = options.AutoCompleteMessages,
                MaxAutoLockRenewalDuration   = options.MaxAutoLockRenewalDuration,
                MaxConcurrentCallsPerSession = options.MaxConcurrentCallsPerSession,
                MaxConcurrentSessions        = options.MaxConcurrentSessions,
                ReceiveMode        = options.ReceiveAndDelete ? ServiceBusReceiveMode.ReceiveAndDelete : ServiceBusReceiveMode.PeekLock,
                SessionIdleTimeout = options.SessionIdleTimeout,
            });

            processor.ProcessMessageAsync += async arg =>
            {
                var result = await received(
                    new MessageArgs
                {
                    Data      = arg.Message.Body,
                    MessageId = arg.Message.MessageId,
                },
                    arg.CancellationToken);

                if (!options.AutoCompleteMessages)
                {
                    if (result)
                    {
                        await arg.CompleteMessageAsync(arg.Message, arg.CancellationToken);
                    }
                    else
                    {
                        await arg.AbandonMessageAsync(arg.Message, new Dictionary <string, object>
                        {
                            { "DeliveryCount", arg.Message.DeliveryCount + 1 },
                        });
                    }
                }
            };
            processor.ProcessErrorAsync += async arg =>
            {
                await ExceptionReceivedHandler(arg);
            };
            await processor.StartProcessingAsync(cancellationToken);

            cancellationToken.Register(async() =>
            {
                await processor.StopProcessingAsync();
            });
        }