public Task StartAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); if (_started) { throw new InvalidOperationException("The listener has already been started."); } if (_isSessionsEnabled) { _clientEntity = _messagingProvider.CreateClientEntity(_entityPath, _serviceBusAccount.ConnectionString); if (_clientEntity is QueueClient queueClient) { queueClient.RegisterSessionHandler(ProcessSessionMessageAsync, _serviceBusOptions.SessionHandlerOptions); } else { SubscriptionClient subscriptionClient = _clientEntity as SubscriptionClient; subscriptionClient.RegisterSessionHandler(ProcessSessionMessageAsync, _serviceBusOptions.SessionHandlerOptions); } } else { _receiver = _messagingProvider.CreateMessageReceiver(_entityPath, _serviceBusAccount.ConnectionString); _receiver.RegisterMessageHandler(ProcessMessageAsync, _serviceBusOptions.MessageHandlerOptions); } _started = true; return(Task.CompletedTask); }
public void Listening(TimeSpan timeout, CancellationToken cancellationToken) { ConnectAsync().GetAwaiter().GetResult(); if (_asbOptions.EnableSessions) { _consumerClient.RegisterSessionHandler(OnConsumerReceivedWithSession, new SessionHandlerOptions(OnExceptionReceived) { AutoComplete = false, MaxAutoRenewDuration = TimeSpan.FromSeconds(30) }); } else { _consumerClient.RegisterMessageHandler(OnConsumerReceived, new MessageHandlerOptions(OnExceptionReceived) { AutoComplete = false, MaxConcurrentCalls = 10, MaxAutoRenewDuration = TimeSpan.FromSeconds(30) }); } while (true) { cancellationToken.ThrowIfCancellationRequested(); cancellationToken.WaitHandle.WaitOne(timeout); } // ReSharper disable once FunctionNeverReturns }
async Task OnSessionExceptionHandlerCalledWhenRegisteredOnNonSessionFulSubscription() { bool exceptionReceivedHandlerCalled = false; var topicClient = new TopicClient(TestUtility.NamespaceConnectionString, TestConstants.NonPartitionedTopicName); var subscriptionClient = new SubscriptionClient( TestUtility.NamespaceConnectionString, topicClient.TopicName, TestConstants.SubscriptionName, ReceiveMode.PeekLock); SessionHandlerOptions sessionHandlerOptions = new SessionHandlerOptions( (eventArgs) => { Assert.NotNull(eventArgs); Assert.NotNull(eventArgs.Exception); if (eventArgs.Exception is InvalidOperationException) { exceptionReceivedHandlerCalled = true; } return(Task.CompletedTask); }) { MaxConcurrentSessions = 1 }; subscriptionClient.RegisterSessionHandler( (session, message, token) => { return(Task.CompletedTask); }, sessionHandlerOptions); try { Stopwatch stopwatch = Stopwatch.StartNew(); while (stopwatch.Elapsed.TotalSeconds <= 10) { if (exceptionReceivedHandlerCalled) { break; } await Task.Delay(TimeSpan.FromSeconds(1)); } TestUtility.Log($"{DateTime.Now}: ExceptionReceivedHandlerCalled: {exceptionReceivedHandlerCalled}"); Assert.True(exceptionReceivedHandlerCalled); } finally { await subscriptionClient.CloseAsync(); await topicClient.CloseAsync(); } }
private static async Task ReceiveMessages_FromTopicSessionStateSubscriptionsAsync(SubscriptionClient client, CancellationToken token, ConsoleColor color, int EndCount) { var doneReceiving = new TaskCompletionSource <bool>(); token.Register( async() => { await client.CloseAsync(); doneReceiving.SetResult(true); }); client.RegisterSessionHandler( async(session, message, token1) => { try { var stateData = await session.GetStateAsync(); var session_state = stateData != null ? Utils.Deserialize <SessionStateManager>(stateData) : new SessionStateManager(); if ((int)message.UserProperties["Count"] == session_state.LastProcessedCount + 1) //check if message is next in the sequence { if (ProcessMessages(message, Color.White)) { await session.CompleteAsync(message.SystemProperties.LockToken); if (((int)message.UserProperties["Count"]) == EndCount) { //end of the session await session.CloseAsync(); } } else { await client.DeadLetterAsync(message.SystemProperties.LockToken, "Message is of the wrong type", "Cannot deserialize this message as the type in the Labl prop is uknown."); } } else { session_state.DeferredList.Add((int)message.UserProperties["Count"], message.SystemProperties.SequenceNumber); await session.DeferAsync(message.SystemProperties.LockToken); await session.SetStateAsync(Utils.Serialize <SessionStateManager>(session_state)); } long last_processed = await ProcessNextMessagesWithSessionStateAsync(client, session, session_state, EndCount, color); } catch (Exception ex) { Log.Error("Unable to receive {0} from subscription: Exception {1}", message.MessageId, ex); } }, GetDefaultSessionHandlingOptions()); await doneReceiving.Task; }
private void AcceptSession(CancellationToken cancellationToken) { this.dynamicThrottling.WaitUntilAllowedParallelism(cancellationToken); if (!cancellationToken.IsCancellationRequested) { // Initialize a custom action acting as a callback whenever a non-transient exception occurs while accepting a session. Func <Exception, Task> recoverAcceptSession = ex => { // Just log an exception. Do not allow an unhandled exception to terminate the message receive loop abnormally. logger.LogWarning($"An unrecoverable error occurred while trying to accept a session in subscription \"{subscription}\":\r\n{ex.Message}"); this.dynamicThrottling.Penalize(); return(Task.CompletedTask); /* * if (!cancellationToken.IsCancellationRequested) * { * // Continue accepting new sessions until told to stop regardless of any exceptions. * return TaskEx.Delay(10000).ContinueWith(t => AcceptSession(cancellationToken)); * } * else * { * return Task.FromResult(0); * }*/ }; try { this.dynamicThrottling.NotifyWorkStarted(); client.RegisterSessionHandler(ReceiveMessagesAndCloseSession, new SessionHandlerOptions(evArgs => { return(recoverAcceptSession(evArgs.Exception)); }) { AutoComplete = false, MaxAutoRenewDuration = TimeSpan.FromMinutes(30), MaxConcurrentSessions = 1 }); } catch (Exception ex) { logger.LogWarning($"The client \"{client.Path}\" already registered. Message is : {ex.Message}"); } /* * this.receiveRetryPolicy.ExecuteAsync(() => { * return Task.Run( * () => { * back code here * }); * }); */ } }
void OnSessionHandlerShouldFailOnNonSessionFulQueue() { var topicClient = new TopicClient(TestUtility.NamespaceConnectionString, TestConstants.NonPartitionedTopicName); var subscriptionClient = new SubscriptionClient( TestUtility.NamespaceConnectionString, topicClient.TopicName, TestConstants.SubscriptionName, ReceiveMode.PeekLock); Assert.Throws <InvalidOperationException>( () => subscriptionClient.RegisterSessionHandler( (session, message, token) => { return(Task.CompletedTask); })); }
private static async Task ReceiveMessages_FromTopicSessionSubscriptionsAsync(SubscriptionClient client, CancellationToken token, ConsoleColor color, int EndCount) { var doneReceiving = new TaskCompletionSource <bool>(); token.Register( async() => { await client.CloseAsync(); doneReceiving.SetResult(true); }); client.RegisterSessionHandler( async(session, message, token1) => { try { Utils.ConsoleWrite($"[{message.SessionId}]\n", ConsoleColor.Blue, ConsoleColor.Red); if (ProcessMessages(message, Color.White)) { await session.CompleteAsync(message.SystemProperties.LockToken); if (((int)message.UserProperties["Count"]) == EndCount) { //end of the session await session.CloseAsync(); } } else { await client.DeadLetterAsync(message.SystemProperties.LockToken, "Message is of the wrong type", "Cannot deserialize this message as the type in the Label prop is unknown."); } } catch (Exception ex) { Log.Error("Unable to receive {0} from subscription: Exception {1}", message.MessageId, ex); } }, GetDefaultSessionHandlingOptions()); await doneReceiving.Task; }
private void RegisterSubscriptionClientSessionMessageHandler(SubscriptionClient subscriptionClient) { subscriptionClient.RegisterSessionHandler(async(session, message, token) => { _log.Trace($"Received Message {message.MessageId} session {session.SessionId} {message.Label} for {subscriptionClient.ServiceBusConnection.Endpoint}"); if (!token.IsCancellationRequested && !subscriptionClient.IsClosedOrClosing && !session.IsClosedOrClosing) { await OnMessageReceived(message); await session.CompleteAsync(message.SystemProperties.LockToken); //TODO: Session to be closed based on the message.Not for all messages. await session.CloseAsync(); } else { _log.Warn($"SubscriptionClient MessageReceived CancellationRequested or IsClosedOrClosing"); await session.AbandonAsync(message.SystemProperties.LockToken); } }, new SessionHandlerOptions(ExceptionReceivedHandler) { AutoComplete = false, MaxConcurrentSessions = 1, MaxAutoRenewDuration = TimeSpan.FromSeconds(60) }); }
private async Task ReceiveMessages_FromTopicSessionStateSubscriptionsAsync(SubscriptionClient client, CancellationToken token, ConsoleColor color) { var doneReceiving = new TaskCompletionSource <bool>(); token.Register( async() => { await client.CloseAsync(); doneReceiving.SetResult(true); }); client.RegisterSessionHandler( async(session, message, token1) => { try { var stateData = await session.GetStateAsync(); var session_state = stateData != null ? Deserialize <SessionStateManager>(stateData) : new SessionStateManager(); if ((int)message.UserProperties["Order"] == session_state.LastProcessedCount + 1) //check if message is next in the sequence { if (ProcessMessages(message, color)) { await session.CompleteAsync(message.SystemProperties.LockToken); session_state.LastProcessedCount = ((int)message.UserProperties["Order"]); await session.SetStateAsync(Serialize <SessionStateManager>(session_state)); if (message.UserProperties["IsLast"].ToString().ToLower() == "true") { //end of the session await session.SetStateAsync(null); await session.CloseAsync(); } } else { await client.DeadLetterAsync(message.SystemProperties.LockToken, "Message is of the wrong type or could not be processed", "Cannot deserialize this message as the type is unknown."); } } else { session_state.DeferredList.Add((int)message.UserProperties["Order"], message.SystemProperties.SequenceNumber); await session.DeferAsync(message.SystemProperties.LockToken); await session.SetStateAsync(Serialize(session_state)); } long last_processed = await ProcessNextMessagesWithSessionStateAsync(client, session, session_state, color); } catch (Exception ex) { Console.WriteLine("-->> ERROR : Unable to receive {0} from subscription: Exception {1}", message.MessageId, ex); } }, new SessionHandlerOptions(e => LogMessageHandlerException(e)) { MessageWaitTimeout = TimeSpan.FromSeconds(5), MaxConcurrentSessions = 1, AutoComplete = false }); await doneReceiving.Task; }