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; }
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(); } }
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); }
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)); }
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; } }
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;
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); }
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(); }
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..."); }
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())); }
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); }
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)); }
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); }
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); }
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(); }
/// <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(); }
/// <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); }