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); }
public void ProcessorOptionsValidation() { var options = new ServiceBusSessionProcessorOptions(); Assert.That( () => options.PrefetchCount = -1, Throws.InstanceOf <ArgumentOutOfRangeException>()); Assert.That( () => options.MaxConcurrentSessions = 0, Throws.InstanceOf <ArgumentOutOfRangeException>()); Assert.That( () => options.MaxConcurrentCallsPerSession = -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); }
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 static PluginSessionProcessor CreatePluginSessionProcessor( this ServiceBusClient client, string queueName, IEnumerable <Func <ServiceBusReceivedMessage, Task> > plugins, ServiceBusSessionProcessorOptions options = default) { return(new PluginSessionProcessor(queueName, client, plugins, options ?? new ServiceBusSessionProcessorOptions())); }
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(); }
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;
public void ToSessionProcessorOptions_DynamicConcurrencyEnabled_ReturnsExpectedValue() { ServiceBusOptions sbOptions = new ServiceBusOptions { AutoCompleteMessages = false, PrefetchCount = 123, MaxAutoLockRenewalDuration = TimeSpan.FromSeconds(123), SessionIdleTimeout = TimeSpan.FromSeconds(123), MaxConcurrentSessions = 123 }; ServiceBusSessionProcessorOptions processorOptions = sbOptions.ToSessionProcessorOptions(true, true); Assert.AreEqual(true, processorOptions.AutoCompleteMessages); Assert.AreEqual(sbOptions.PrefetchCount, processorOptions.PrefetchCount); Assert.AreEqual(sbOptions.MaxAutoLockRenewalDuration, processorOptions.MaxAutoLockRenewalDuration); Assert.AreEqual(sbOptions.SessionIdleTimeout, processorOptions.SessionIdleTimeout); Assert.AreEqual(1, processorOptions.MaxConcurrentSessions); }
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(); }
protected virtual ServiceBusSessionProcessor GetAzureServiceBusSessionProcessor() { //Configure additional options... var sessionProcessorOptions = new ServiceBusSessionProcessorOptions() { AutoCompleteMessages = false, ReceiveMode = ServiceBusReceiveMode.PeekLock }; if (this.Options.PrefetchCount > 0) { sessionProcessorOptions.PrefetchCount = this.Options.PrefetchCount; } if (this.Options.MaxConcurrentReceiversOrSessions > 0) { sessionProcessorOptions.MaxConcurrentSessions = this.Options.MaxConcurrentReceiversOrSessions; } //Good Detail Summary of this property is at: https://stackoverflow.com/a/60381046/7293142 if (this.Options.MaxAutoRenewDuration.HasValue) { sessionProcessorOptions.MaxAutoLockRenewalDuration = this.Options.MaxAutoRenewDuration.Value; } if (this.Options.SessionConnectionIdleTimeout.HasValue) { sessionProcessorOptions.SessionIdleTimeout = this.Options.SessionConnectionIdleTimeout.Value; } var sessionProcessingClient = this.AzureServiceBusClient.CreateSessionProcessor( this.ServiceBusTopic, this.ServiceBusSubscription, sessionProcessorOptions ); return(sessionProcessingClient); }
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)); }
public async Task ProcessSessionMessages() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true)) { string connectionString = TestEnvironment.ServiceBusConnectionString; string queueName = scope.QueueName; await using var client = GetClient(); #region Snippet:ServiceBusProcessSessionMessages //@@ string connectionString = "<connection_string>"; //@@ string queueName = "<queue_name>"; // since ServiceBusClient implements IAsyncDisposable we create it with "await using" //@@ await using var client = new ServiceBusClient(connectionString); // create the sender ServiceBusSender sender = client.CreateSender(queueName); // create a message batch that we can send ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync(); messageBatch.TryAddMessage( new ServiceBusMessage(Encoding.UTF8.GetBytes("First")) { SessionId = "Session1" }); messageBatch.TryAddMessage( new ServiceBusMessage(Encoding.UTF8.GetBytes("Second")) { SessionId = "Session2" }); // send the message batch await sender.SendMessagesAsync(messageBatch); // 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 session processor that we can use to process the messages ServiceBusSessionProcessor processor = client.CreateSessionProcessor(queueName, options); // since the message handler will run in a background thread, in order to prevent // this sample from terminating immediately, we can use a task completion source that // we complete from within the message handler. TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); int processedMessageCount = 0; processor.ProcessMessageAsync += MessageHandler; processor.ProcessErrorAsync += ErrorHandler; async Task MessageHandler(ProcessSessionMessageEventArgs args) { var body = args.Message.Body.ToString(); // we can evaluate application logic and use that to determine how to settle the message. await args.CompleteMessageAsync(args.Message); // we can also set arbitrary session state using this receiver // the state is specific to the session, and not any particular message await args.SetSessionStateAsync(new BinaryData("some state")); // Once we've received the last message, complete the // task completion source. if (Interlocked.Increment(ref processedMessageCount) == 2) { tcs.SetResult(true); } } Task ErrorHandler(ProcessErrorEventArgs args) { // the error source tells me at what point in the processing an error occurred Console.WriteLine(args.ErrorSource); // the fully qualified namespace is available Console.WriteLine(args.FullyQualifiedNamespace); // as well as the entity path Console.WriteLine(args.EntityPath); Console.WriteLine(args.Exception.ToString()); return(Task.CompletedTask); } await processor.StartProcessingAsync(); // await our task completion source task so that the message handler will be invoked at least once. await tcs.Task; // stop processing once the task completion source was completed. await processor.StopProcessingAsync(); #endregion } }
public async Task ProcessSessionMessages() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true)) { #region Snippet:ServiceBusProcessSessionMessages #if SNIPPET string connectionString = "<connection_string>"; string queueName = "<queue_name>"; // since ServiceBusClient implements IAsyncDisposable we create it with "await using" await using var client = new ServiceBusClient(connectionString); #else string connectionString = TestEnvironment.ServiceBusConnectionString; string queueName = scope.QueueName; await using var client = CreateClient(); #endif // create the sender ServiceBusSender sender = client.CreateSender(queueName); // create a message batch that we can send ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync(); messageBatch.TryAddMessage( new ServiceBusMessage("First") { SessionId = "Session1" }); messageBatch.TryAddMessage( new ServiceBusMessage("Second") { SessionId = "Session2" }); // send the message batch await sender.SendMessagesAsync(messageBatch); #region Snippet:ServiceBusConfigureSessionProcessor // create 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 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. MaxConcurrentCallsPerSession = 2, // Processing can be optionally limited to a subset of session Ids. SessionIds = { "my-session", "your-session" }, }; // create a session processor that we can use to process the messages await using ServiceBusSessionProcessor processor = client.CreateSessionProcessor(queueName, options); // configure the message and error handler to use processor.ProcessMessageAsync += MessageHandler; processor.ProcessErrorAsync += ErrorHandler; async Task MessageHandler(ProcessSessionMessageEventArgs args) { var body = args.Message.Body.ToString(); // we can evaluate application logic and use that to determine how to settle the message. await args.CompleteMessageAsync(args.Message); // we can also set arbitrary session state using this receiver // the state is specific to the session, and not any particular message await args.SetSessionStateAsync(new BinaryData("some state")); } Task ErrorHandler(ProcessErrorEventArgs args) { // the error source tells me at what point in the processing an error occurred Console.WriteLine(args.ErrorSource); // the fully qualified namespace is available Console.WriteLine(args.FullyQualifiedNamespace); // as well as the entity path Console.WriteLine(args.EntityPath); 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. Console.ReadKey(); #endregion #endregion } }
internal PluginSessionProcessor(string topicName, string subscriptionName, ServiceBusClient client, IEnumerable <Func <ServiceBusReceivedMessage, Task> > plugins, ServiceBusSessionProcessorOptions options) : base(client, topicName, subscriptionName, options) { _plugins = plugins; }