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
        }
Esempio n. 3
0
        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;
        }
Esempio n. 5
0
        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;
        }
Esempio n. 8
0
 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;
        }