Example #1
0
        public Worker(
            string queueOrTopic,
            string?subscription,
            Func <Worker, ProcessErrorEventArgs, Task> errorCallback,
            ServiceBusClient serviceBusClient,
            ServiceBusAdministrationClient administrationClient,
            IServiceScopeFactory serviceScopeFactory,
            IOptions <AzureServiceBusOptions> options,
            ILogger <Worker> logger)
        {
            QueueOrTopic          = queueOrTopic;
            Subscription          = subscription == "" ? null : subscription;
            ServiceBusClient      = serviceBusClient;
            _errorCallback        = errorCallback;
            _administrationClient = administrationClient;
            _serviceScopeFactory  = serviceScopeFactory;
            _logger = logger;

            var processorOptions = new ServiceBusProcessorOptions
            {
                MaxConcurrentCalls = options.Value.MaxConcurrentCalls
            };

            _processor = string.IsNullOrEmpty(subscription) ? serviceBusClient.CreateProcessor(queueOrTopic, processorOptions) : serviceBusClient.CreateProcessor(queueOrTopic, subscription, processorOptions);
            _processor.ProcessMessageAsync += OnMessageReceivedAsync;
            _processor.ProcessErrorAsync   += OnErrorAsync;
        }
Example #2
0
        public async Task <ServiceBusProcessor> GetReceiverClient <T>(ServiceBusProcessorOptions options) where T : ICommand
        {
            if (ReceiverClients.TryGetValue(typeof(T), out var client))
            {
                return(client);
            }

            try
            {
                // No existing client found, try and create one making sure parallel threads do not compete
                await _semaphore.WaitAsync().ConfigureAwait(false);

                // After we have waited, another thread might have created the client we're looking for
                if (ReceiverClients.TryGetValue(typeof(T), out client))
                {
                    return(client);
                }

                client = CreateReceiverClient <T>(options);
                return(ReceiverClients.GetOrAdd(typeof(T), client));
            }
            finally
            {
                _semaphore.Release();
            }
        }
Example #3
0
        public void ProcessorOptionsValidation()
        {
            var options = new ServiceBusProcessorOptions();

            Assert.That(
                () => options.PrefetchCount = -1,
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxConcurrentCalls = 0,
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxConcurrentCalls = -1,
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxAutoLockRenewalDuration = TimeSpan.FromSeconds(-1),
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxReceiveWaitTime = TimeSpan.FromSeconds(0),
                Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(
                () => options.MaxReceiveWaitTime = TimeSpan.FromSeconds(-1),
                Throws.InstanceOf <ArgumentOutOfRangeException>());

            // should not throw
            options.PrefetchCount              = 0;
            options.MaxReceiveWaitTime         = TimeSpan.FromSeconds(1);
            options.MaxAutoLockRenewalDuration = TimeSpan.FromSeconds(0);
        }
        protected virtual ServiceBusProcessor GetAzureServiceBusProcessor()
        {
            //Configure additional options...
            var processorOptions = new ServiceBusProcessorOptions()
            {
                AutoCompleteMessages = false,
                ReceiveMode          = ServiceBusReceiveMode.PeekLock
            };

            if (this.Options.PrefetchCount > 0)
            {
                processorOptions.PrefetchCount = this.Options.PrefetchCount;
            }

            if (this.Options.MaxConcurrentReceiversOrSessions > 0)
            {
                processorOptions.MaxConcurrentCalls = this.Options.MaxConcurrentReceiversOrSessions;
            }

            if (this.Options.MaxAutoRenewDuration.HasValue)
            {
                processorOptions.MaxAutoLockRenewalDuration = this.Options.MaxAutoRenewDuration.Value;
            }

            var serviceBusProcessingClient = this.AzureServiceBusClient.CreateProcessor(
                this.ServiceBusTopic,
                this.ServiceBusSubscription,
                processorOptions
                );

            return(serviceBusProcessingClient);
        }
Example #5
0
        private ServiceBusProcessor CreateReceiverClient <T>(ServiceBusProcessorOptions options) where T : ICommand
        {
            var queueName = AutoMessageMapper.GetQueueName <T>();
            var client    = new ServiceBusClient(_connectionString);

            return(client.CreateProcessor(queueName, options));
        }
        public void Setup()
        {
            _mockExecutor = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);
            var client = new ServiceBusClient(_testConnection);
            ServiceBusProcessorOptions processorOptions = new ServiceBusProcessorOptions();
            ServiceBusProcessor        messageProcessor = client.CreateProcessor(_entityPath);

            _mockMessageProcessor = new Mock <MessageProcessor>(MockBehavior.Strict, messageProcessor);

            _serviceBusOptions     = new ServiceBusOptions();
            _mockMessagingProvider = new Mock <MessagingProvider>(MockBehavior.Strict, new OptionsWrapper <ServiceBusOptions>(_serviceBusOptions));

            _mockMessagingProvider
            .Setup(p => p.CreateMessageProcessor(_entityPath, _testConnection))
            .Returns(_mockMessageProcessor.Object);

            _mockServiceBusAccount = new Mock <ServiceBusAccount>(MockBehavior.Strict);
            _mockServiceBusAccount.Setup(a => a.ConnectionString).Returns(_testConnection);

            _loggerFactory  = new LoggerFactory();
            _loggerProvider = new TestLoggerProvider();
            _loggerFactory.AddProvider(_loggerProvider);

            _listener = new ServiceBusListener(_functionId, EntityType.Queue, _entityPath, false, _mockExecutor.Object, _serviceBusOptions, _mockServiceBusAccount.Object,
                                               _mockMessagingProvider.Object, _loggerFactory, false);
            _scaleMonitor = (ServiceBusScaleMonitor)_listener.GetMonitor();
        }
        /// <summary>
        /// Subscriber to message queue.
        /// </summary>
        /// <param name="cancellationToken">The cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>Task.</returns>
        public virtual Task SubscribeToMessageBusAsync(CancellationToken cancellationToken = default)
        {
            _serviceBusClient = new ServiceBusClient(_option.ConnectionString);

            // create the options to use for configuring the processor
            var options = new ServiceBusProcessorOptions
            {
                // By default or when AutoCompleteMessages is set to true, the processor will complete the message after executing the message handler
                // Set AutoCompleteMessages to false to [settle messages](https://docs.microsoft.com/en-us/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock) on your own.
                // In both cases, if the message handler throws an exception without settling the message, the processor will abandon the message.
                AutoCompleteMessages = false,
                // I can also allow for multi-threading
                MaxConcurrentCalls = 2,
                ReceiveMode        = ServiceBusReceiveMode.PeekLock
            };

            // create a processor that we can use to process the messages
            _serviceBusProcessor = _serviceBusClient.CreateProcessor(_option.QueueName, options);

            // configure the message and error handler to use
            _serviceBusProcessor.ProcessMessageAsync += MessageHandlerAsync;
            _serviceBusProcessor.ProcessErrorAsync   += ErrorHandlerAsync;

            // start processing
            return(_serviceBusProcessor.StartProcessingAsync(cancellationToken));
        }
Example #8
0
        private async Task Process(CancellationToken cancellationToken)
        {
            var options = new ServiceBusProcessorOptions()
            {
                MaxConcurrentCalls = Options.MaxConcurrentCalls
            };

            await using var processor = ServiceBusClient.CreateProcessor(QueueName);

            try
            {
                processor.ProcessMessageAsync += MessageHandler;
                processor.ProcessErrorAsync   += ErrorHandler;
                await processor.StartProcessingAsync(cancellationToken);

                // Block until token is cancelled
                await Task.Delay(Timeout.InfiniteTimeSpan, cancellationToken);
            }
            catch (OperationCanceledException)
            {
            }
            finally
            {
                // Do not flow cancellationToken since we always want to wait for processing to finish
                await processor.StopProcessingAsync();

                processor.ProcessMessageAsync -= MessageHandler;
                processor.ProcessErrorAsync   -= ErrorHandler;
            }
        }
Example #9
0
        private static async Task ReceiveTextMessage()
        {
            const string queueName = "sbq-text-message";

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

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

            Console.WriteLine($"Receiving messages for {nameof(ReceiveTextMessage)}...");

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

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

                // I can also allow for multi-threading
                MaxConcurrentCalls = 2
            };

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

            processor.ProcessMessageAsync += MessageHandler;
            processor.ProcessErrorAsync   += ErrorHandler;
Example #10
0
        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 ServiceBusProcessorOptions
            {
                AutoComplete               = false,
                MaxConcurrentCalls         = 10,
                PrefetchCount              = 5,
                ReceiveMode                = ReceiveMode.ReceiveAndDelete,
                MaxAutoLockRenewalDuration = TimeSpan.FromSeconds(60),
                MaxReceiveWaitTime         = TimeSpan.FromSeconds(10)
            };
            var processor = client.CreateProcessor("queueName", options);

            Assert.AreEqual(options.AutoComplete, processor.AutoComplete);
            Assert.AreEqual(options.MaxConcurrentCalls, processor.MaxConcurrentCalls);
            Assert.AreEqual(options.PrefetchCount, processor.PrefetchCount);
            Assert.AreEqual(options.ReceiveMode, processor.ReceiveMode);
            Assert.AreEqual(options.MaxAutoLockRenewalDuration, processor.MaxAutoLockRenewalDuration);
            Assert.AreEqual(fullyQualifiedNamespace, processor.FullyQualifiedNamespace);
            Assert.IsFalse(processor.IsClosed);
            Assert.IsFalse(processor.IsProcessing);
        }
Example #11
0
        public Worker(
            string queueOrTopic,
            string?subscription,
            string tag,
            ServiceBusClient serviceBusClient,
            ServiceBusAdministrationClient administrationClient,
            IClock clock,
            IServiceScopeFactory serviceScopeFactory,
            IOptions <AzureServiceBusOptions> options,
            ILogger <Worker> logger)
        {
            QueueOrTopic          = queueOrTopic;
            Subscription          = subscription == "" ? null : subscription;
            Tag                   = tag;
            ServiceBusClient      = serviceBusClient;
            _administrationClient = administrationClient;
            _clock                = clock;
            _serviceScopeFactory  = serviceScopeFactory;
            _logger               = logger;

            var processorOptions = new ServiceBusProcessorOptions
            {
                MaxConcurrentCalls = options.Value.MaxConcurrentCalls
            };

            _processor = subscription == null?serviceBusClient.CreateProcessor(queueOrTopic, processorOptions) : serviceBusClient.CreateProcessor(queueOrTopic, subscription, processorOptions);

            _processor.ProcessMessageAsync += OnMessageReceivedAsync;
            _processor.ProcessErrorAsync   += OnErrorAsync;
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            await using var client = new ServiceBusClient(connectionString);

            var options = new ServiceBusProcessorOptions
            {
                AutoCompleteMessages = false
            };

            await using var queueProcessor      = client.CreateProcessor(config.Queue, options);
            queueProcessor.ProcessMessageAsync += MessageHandler;
            queueProcessor.ProcessErrorAsync   += ErrorHandler;


            await using var subscriptionProcessor      = client.CreateProcessor(config.Topic, config.Subscription, options);
            subscriptionProcessor.ProcessMessageAsync += MessageHandler;
            subscriptionProcessor.ProcessErrorAsync   += ErrorHandler;

            await queueProcessor.StartProcessingAsync();

            await subscriptionProcessor.StartProcessingAsync();

            while (!stoppingToken.IsCancellationRequested)
            {
                await Task.Delay(1);
            }
        }
        static async Task ReceiveSalesMessageAsync()
        {
            Console.WriteLine("======================================================");
            Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
            Console.WriteLine("======================================================");


            var client = new ServiceBusClient(ServiceBusConnectionString);

            var processorOptions = new ServiceBusProcessorOptions
            {
                MaxConcurrentCalls   = 1,
                AutoCompleteMessages = false
            };

            await using ServiceBusProcessor processor = client.CreateProcessor(QueueName, processorOptions);

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


            await processor.StartProcessingAsync();

            Console.Read();

            await processor.CloseAsync();
        }
Example #14
0
        static async Task ReceiveMessageAsync()
        {
            Console.WriteLine("=========================================================");
            Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
            Console.WriteLine("=========================================================");
            var options = new ServiceBusProcessorOptions {
                AutoCompleteMessages = false
            };

            await using ServiceBusProcessor processor = string.IsNullOrWhiteSpace(SubscriptionName) ?
                                                        srv.CreateProcessor(QueueOrTopicName, options) :
                                                        srv.CreateProcessor(QueueOrTopicName, SubscriptionName, options);
            processor.ProcessMessageAsync += async(arg) => {
                Console.WriteLine($"Received message: SequenceNumber: {arg.Message.SequenceNumber} Body: {Encoding.UTF8.GetString(arg.Message.Body)}");
                // Console.WriteLine($"Received message: SequenceNumber: {arg.Message.SequenceNumber} Body: {arg.Message.As<Item>().ToString()}");
                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 processor...");
        }
Example #15
0
 public static PluginProcessor CreatePluginProcessor(
     this ServiceBusClient client,
     string queueName,
     IEnumerable <Func <ServiceBusReceivedMessage, Task> > plugins,
     ServiceBusProcessorOptions options = default)
 {
     return(new PluginProcessor(queueName, client, plugins, options ?? new ServiceBusProcessorOptions()));
 }
Example #16
0
        static async Task Main(string[] args)
        {
            var _serviceBusConfig = new
            {
                ConnectionsString = "",
                QueueName         = ""
            };

            // create the options to use for configuring the processor
            var options = new ServiceBusProcessorOptions
            {
                // By default or when AutoCompleteMessages is set to true, the processor will complete the message after executing the message handler
                // Set AutoCompleteMessages to false to [settle messages](https://docs.microsoft.com/en-us/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock) on your own.
                // In both cases, if the message handler throws an exception without settling the message, the processor will abandon the message.
                AutoCompleteMessages = false,

                // I can also allow for multi-threading
                MaxConcurrentCalls = 2
            };

            // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
            await using var client = new ServiceBusClient(_serviceBusConfig.ConnectionsString);

            // create a processor that we can use to process the messages
            await using ServiceBusProcessor processor = client.CreateProcessor(_serviceBusConfig.QueueName, options);

            // configure the message and error handler to use
            processor.ProcessMessageAsync += MessageHandler;
            processor.ProcessErrorAsync   += ErrorHandler;

            async Task MessageHandler(ProcessMessageEventArgs args)
            {
                string body = args.Message.Body.ToString();

                System.Console.WriteLine(body);

                // we can evaluate application logic and use that to determine how to settle the message.
                await args.CompleteMessageAsync(args.Message);
            }

            Task ErrorHandler(ProcessErrorEventArgs args)
            {
                // the error source tells me at what point in the processing an error occurred
                System.Console.WriteLine(args.ErrorSource);
                // the fully qualified namespace is available
                System.Console.WriteLine(args.FullyQualifiedNamespace);
                // as well as the entity path
                System.Console.WriteLine(args.EntityPath);
                System.Console.WriteLine(args.Exception.ToString());
                return(Task.CompletedTask);
            }

            // start processing
            await processor.StartProcessingAsync();

            // since the processing happens in the background, we add a Conole.ReadKey to allow the processing to continue until a key is pressed.
            System.Console.ReadKey();
        }
        public async Task CanStopProcessingFromHandler(int numThreads)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(
                             enablePartitioning: false,
                             enableSession: false))
            {
                await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);
                int numMessages         = 100;
                using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync();

                ServiceBusMessageBatch messageBatch = AddMessages(batch, numMessages);

                await sender.SendMessagesAsync(messageBatch);

                var options = new ServiceBusProcessorOptions
                {
                    MaxConcurrentCalls = numThreads,
                    ReceiveMode        = ReceiveMode.ReceiveAndDelete
                };
                var processor          = client.CreateProcessor(scope.QueueName, options);
                int messageProcessedCt = 0;

                // stop processing halfway through
                int stopAfterMessagesCt = numMessages / 2;

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

                await processor.StartProcessingAsync();

                Task ProcessMessage(ProcessMessageEventArgs args)
                {
                    var currentCt = Interlocked.Increment(ref messageProcessedCt);

                    if (currentCt == stopAfterMessagesCt)
                    {
                        // awaiting here would cause a deadlock
                        _ = processor.StopProcessingAsync();
                        tcs.SetResult(true);
                    }
                    return(Task.CompletedTask);
                }

                await tcs.Task;

                var receiver         = GetNoRetryClient().CreateReceiver(scope.QueueName);
                var receivedMessages = await receiver.ReceiveMessagesAsync(numMessages);

                // 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(receivedMessages.Count > 0);
                Assert.IsTrue(messageProcessedCt < numMessages);
            }
        }
        private static async Task Main(string[] args)
        {
            await using var stage = 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);
            await sender.SendMessageAsync(new ServiceBusMessage(UTF8.GetBytes("Deep Dive")));

            WriteLine("Message sent");

            var processorOptions = new ServiceBusProcessorOptions
            {
                AutoCompleteMessages       = false,
                MaxConcurrentCalls         = 1,
                MaxAutoLockRenewalDuration = TimeSpan.FromMinutes(10),
                ReceiveMode   = ServiceBusReceiveMode.PeekLock,
                PrefetchCount = 10
            };

            await using var receiver      = serviceBusClient.CreateProcessor(destination, processorOptions);
            receiver.ProcessMessageAsync += async messageEventArgs =>
            {
                var message = messageEventArgs.Message;
                await Out.WriteLineAsync(
                    $"Received message with '{message.MessageId}' and content '{UTF8.GetString(message.Body)}'");

                // throw new InvalidOperationException();
                await messageEventArgs.CompleteMessageAsync(message);

                syncEvent.TrySetResult(true);
            };
            receiver.ProcessErrorAsync += async errorEventArgs =>
            {
                await Out.WriteLineAsync($"Exception: {errorEventArgs.Exception}");

                await Out.WriteLineAsync($"FullyQualifiedNamespace: {errorEventArgs.FullyQualifiedNamespace}");

                await Out.WriteLineAsync($"ErrorSource: {errorEventArgs.ErrorSource}");

                await Out.WriteLineAsync($"EntityPath: {errorEventArgs.EntityPath}");
            };

            await receiver.StartProcessingAsync();

            await syncEvent.Task;

            await receiver.StopProcessingAsync();
        }
        private ServiceBusProcessor CreateProcessor(ServiceBusClient client, string entityName, string subscriptionName)
        {
            ServiceBusProcessorOptions options = DetermineMessageProcessorOptions();

            if (string.IsNullOrWhiteSpace(subscriptionName))
            {
                return(client.CreateProcessor(entityName, options));
            }

            return(client.CreateProcessor(entityName, subscriptionName, options));
        }
        public void Setup()
        {
            _mockExecutor = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);
            _client       = new ServiceBusClient(_testConnection);
            ServiceBusProcessorOptions processorOptions = new ServiceBusProcessorOptions();
            ServiceBusProcessor        messageProcessor = _client.CreateProcessor(_entityPath);
            ServiceBusReceiver         receiver         = _client.CreateReceiver(_entityPath);

            _mockMessageProcessor = new Mock <MessageProcessor>(MockBehavior.Strict, messageProcessor);
            var configuration = ConfigurationUtilities.CreateConfiguration(new KeyValuePair <string, string>(_connection, _testConnection));

            _serviceBusOptions = new ServiceBusOptions();
            _mockProvider      = new Mock <MessagingProvider>(new OptionsWrapper <ServiceBusOptions>(_serviceBusOptions));
            _mockClientFactory = new Mock <ServiceBusClientFactory>(
                configuration,
                Mock.Of <AzureComponentFactory>(),
                _mockProvider.Object,
                new AzureEventSourceLogForwarder(new NullLoggerFactory()),
                new OptionsWrapper <ServiceBusOptions>(_serviceBusOptions));

            _mockProvider
            .Setup(p => p.CreateMessageProcessor(_client, _entityPath, It.IsAny <ServiceBusProcessorOptions>()))
            .Returns(_mockMessageProcessor.Object);

            _mockProvider
            .Setup(p => p.CreateClient(_testConnection, It.IsAny <ServiceBusClientOptions>()))
            .Returns(_client);

            _loggerFactory  = new LoggerFactory();
            _loggerProvider = new TestLoggerProvider();
            _loggerFactory.AddProvider(_loggerProvider);

            var concurrencyOptions             = new OptionsWrapper <ConcurrencyOptions>(new ConcurrencyOptions());
            var mockConcurrencyThrottleManager = new Mock <IConcurrencyThrottleManager>(MockBehavior.Strict);
            var concurrencyManager             = new ConcurrencyManager(concurrencyOptions, _loggerFactory, mockConcurrencyThrottleManager.Object);

            _listener = new ServiceBusListener(
                _functionId,
                ServiceBusEntityType.Queue,
                _entityPath,
                false,
                _serviceBusOptions.AutoCompleteMessages,
                _mockExecutor.Object,
                _serviceBusOptions,
                _connection,
                _mockProvider.Object,
                _loggerFactory,
                false,
                _mockClientFactory.Object,
                concurrencyManager);

            _scaleMonitor = (ServiceBusScaleMonitor)_listener.GetMonitor();
        }
        public ServiceBusProcessor CreateClientProcessor(string eventName)
        {
            var options = new ServiceBusProcessorOptions
            {
                AutoCompleteMessages = azureOptions.Value.AutoComplete ?? false,
                MaxConcurrentCalls   = azureOptions.Value.MaxConcurrent ?? 5
            };
            var connection = this.CreateClientConnection();
            var processor  = connection.CreateProcessor(eventName, azureOptions.Value.Queue, options);

            return(processor);
        }
        private async Task RunServiceProcessorAsync()
        {
            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 ServiceBusProcessorOptions()
            {
                AutoCompleteMessages       = true,
                MaxConcurrentCalls         = this.ConcurrentCalls,
                ReceiveMode                = this.ReceiveDelete ? ServiceBusReceiveMode.ReceiveAndDelete : ServiceBusReceiveMode.PeekLock,
                PrefetchCount              = this.PrefetchCount,
                MaxAutoLockRenewalDuration = TimeSpan.FromMinutes(2)
            };
            var processor = client.CreateProcessor(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();
        }
        private ServiceBusProcessorOptions DetermineMessageProcessorOptions()
        {
            var messageHandlerOptions = new ServiceBusProcessorOptions();

            if (Options != null)
            {
                // Assign the configured defaults
                messageHandlerOptions.AutoCompleteMessages = Options.AutoComplete;
                messageHandlerOptions.MaxConcurrentCalls   = Options.MaxConcurrentCalls ?? messageHandlerOptions.MaxConcurrentCalls;
            }

            return(messageHandlerOptions);
        }
Example #24
0
        public async Task ReceiveMessagesFromSubscriptionAsync(string subscriptionName)
        {
            var options = new ServiceBusProcessorOptions
            {
                AutoCompleteMessages = false,
                MaxConcurrentCalls   = 2,
                ReceiveMode          = ServiceBusReceiveMode.PeekLock
            };
            var processor = _client.CreateProcessor(TopicName, subscriptionName, options);

            processor.ProcessMessageAsync += args => MessageHandler(args, subscriptionName);
            processor.ProcessErrorAsync   += args => ErrorHandler(args, subscriptionName);
            await processor.StartProcessingAsync();
        }
            public override MessageProcessor CreateMessageProcessor(ServiceBusClient client, string entityPath)
            {
                var options = new ServiceBusProcessorOptions()
                {
                    MaxConcurrentCalls         = 3,
                    MaxAutoLockRenewalDuration = TimeSpan.FromMinutes(MaxAutoRenewDurationMin)
                };

                var processor = client.CreateProcessor(entityPath, options);
                var receiver  = client.CreateReceiver(entityPath);

                // TODO decide whether it makes sense to still default error handler when there is a custom provider
                // currently user needs to set it.
                processor.ProcessErrorAsync += args => Task.CompletedTask;
                return(new CustomMessageProcessor(processor, _logger));
            }
Example #26
0
        static ServiceBusProcessorOptions RegisterOptions()
        {
            // Configure the message handler options in terms of exception handling, number of concurrent messages to deliver, etc.
            var messageHandlerOptions = new ServiceBusProcessorOptions
            {
                // Maximum number of concurrent calls to the callback ProcessMessagesAsync(), set to 1 for simplicity.
                // Set it according to how many messages the application wants to process in parallel.
                MaxConcurrentCalls = 1,

                // Indicates whether the message pump should automatically complete the messages after returning from user callback.
                // False below indicates the complete operation is handled by the user callback as in ProcessMessagesAsync().
                AutoCompleteMessages = false,
                //ReceiveMode = ServiceBusReceiveMode.ReceiveAndDelete
            };

            return(messageHandlerOptions);
        }
Example #27
0
        public void ToProcessorOptions_DynamicConcurrencyEnabled_ReturnsExpectedValue()
        {
            ServiceBusOptions sbOptions = new ServiceBusOptions
            {
                AutoCompleteMessages       = false,
                PrefetchCount              = 123,
                MaxAutoLockRenewalDuration = TimeSpan.FromSeconds(123),
                MaxConcurrentCalls         = 123
            };

            ServiceBusProcessorOptions processorOptions = sbOptions.ToProcessorOptions(true, true);

            Assert.AreEqual(true, processorOptions.AutoCompleteMessages);
            Assert.AreEqual(sbOptions.PrefetchCount, processorOptions.PrefetchCount);
            Assert.AreEqual(sbOptions.MaxAutoLockRenewalDuration, processorOptions.MaxAutoLockRenewalDuration);
            Assert.AreEqual(1, processorOptions.MaxConcurrentCalls);
        }
Example #28
0
    public EventBusServiceBus(IServiceBusPersisterConnection serviceBusPersisterConnection,
                              ILogger <EventBusServiceBus> logger, IEventBusSubscriptionsManager subsManager, ILifetimeScope autofac, string subscriptionClientName)
    {
        _serviceBusPersisterConnection = serviceBusPersisterConnection;
        _logger           = logger ?? throw new ArgumentNullException(nameof(logger));
        _subsManager      = subsManager ?? new InMemoryEventBusSubscriptionsManager();
        _autofac          = autofac;
        _subscriptionName = subscriptionClientName;
        _sender           = _serviceBusPersisterConnection.TopicClient.CreateSender(_topicName);
        ServiceBusProcessorOptions options = new ServiceBusProcessorOptions {
            MaxConcurrentCalls = 10, AutoCompleteMessages = false
        };

        _processor = _serviceBusPersisterConnection.TopicClient.CreateProcessor(_topicName, _subscriptionName, options);

        RemoveDefaultRule();
        RegisterSubscriptionClientMessageHandlerAsync().GetAwaiter().GetResult();
    }
Example #29
0
        /// <summary>
        /// Demostrate how to manually Create <see cref="ServiceBusProcessor"/>.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task ProcessAsync(CancellationToken cancellationToken)
        {
            // 1. named value of the connection
            var client = _connections.CreateClient(ServiceBusNames.QueuesOnly);

            var options = new ServiceBusProcessorOptions
            {
                AutoCompleteMessages = false,
                MaxConcurrentCalls   = 1
            };

            // 2. Topic or Queue Name
            var processor = client.CreateProcessor("sendgridwebhook_dev", options);

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

            async Task MessageHandler(ProcessMessageEventArgs args)
            {
                var body = args.Message.Body.ToString();

                _logger.LogInformation(body);

                // we can evaluate application logic and use that to determine how to settle the message.
                await args.CompleteMessageAsync(args.Message);
            }

            Task ErrorHandler(ProcessErrorEventArgs args)
            {
                // the error source tells me at what point in the processing an error occurred
                _logger.LogInformation(args.ErrorSource.ToString());
                // the fully qualified namespace is available
                _logger.LogInformation(args.FullyQualifiedNamespace);
                // as well as the entity path
                _logger.LogInformation(args.EntityPath);
                _logger.LogInformation(args.Exception.ToString());
                return(Task.CompletedTask);
            }

            // start processing
            await processor.StartProcessingAsync();
        }
Example #30
0
        /// <summary>
        /// Creates a ServiceBusClient for azure service bus to listen for notifications.
        /// </summary>
        private async Task StartServiceBusListener()
        {
            await using var client = new ServiceBusClient(this.Config.ServiceBusConnectionString);
            var options = new ServiceBusProcessorOptions
            {
                ReceiveMode = ServiceBusReceiveMode.PeekLock,
            };

            await using ServiceBusProcessor processor = client.CreateProcessor(this.queueName, options);
            processor.ProcessMessageAsync            += ServiceBusMessageHandler;
            processor.ProcessErrorAsync += (ProcessErrorEventArgs args) =>
            {
                Log.Error(args.Exception, $"ServiceBus message handler failure. Source: {args.ErrorSource}; Namespace: {args.FullyQualifiedNamespace}; EntityPath: {args.EntityPath}");
                return(Task.CompletedTask);
            };

            await processor.StartProcessingAsync();

            await Task.Delay(-1);
        }