Пример #1
0
 private Lazy <ServiceBusClient> CreateSessionClient()
 {
     return(new Lazy <ServiceBusClient>(() => _messagingProvider.CreateSessionClient(_serviceBusAccount.ConnectionString)));
 }
Пример #2
0
        internal void StartMessageBatchReceiver(CancellationToken cancellationToken)
        {
            SessionClient    sessionClient = null;
            IMessageReceiver receiver      = null;

            if (_isSessionsEnabled)
            {
                sessionClient = _messagingProvider.CreateSessionClient(_entityPath, _serviceBusAccount.ConnectionString);
            }
            else
            {
                receiver = Receiver;
            }

            Task.Run(async() =>
            {
                while (true)
                {
                    try
                    {
                        if (!_started || cancellationToken.IsCancellationRequested)
                        {
                            return;
                        }

                        if (_isSessionsEnabled)
                        {
                            try
                            {
                                receiver = await sessionClient.AcceptMessageSessionAsync();
                            }
                            catch (ServiceBusTimeoutException)
                            {
                                // it's expected if the entity is empty, try next time
                                continue;
                            }
                        }

                        IList <Message> messages = await receiver.ReceiveAsync(_serviceBusOptions.BatchOptions.MaxMessageCount, _serviceBusOptions.BatchOptions.OperationTimeout);

                        if (messages != null)
                        {
                            Message[] messagesArray      = messages.ToArray();
                            ServiceBusTriggerInput input = ServiceBusTriggerInput.CreateBatch(messagesArray);
                            input.MessageReceiver        = receiver;

                            FunctionResult result = await _triggerExecutor.TryExecuteAsync(input.GetTriggerFunctionData(), cancellationToken);

                            if (cancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            // Complete batch of messages only if the execution was successful
                            if (_serviceBusOptions.BatchOptions.AutoComplete && _started)
                            {
                                if (result.Succeeded)
                                {
                                    await receiver.CompleteAsync(messagesArray.Select(x => x.SystemProperties.LockToken));
                                }
                                else
                                {
                                    // Delivery count is not incremented if
                                    // Session is accepted, the messages within the session are not completed (even if they are locked), and the session is closed
                                    // https://docs.microsoft.com/en-us/azure/service-bus-messaging/message-sessions#impact-of-delivery-count
                                    if (_isSessionsEnabled)
                                    {
                                        List <Task> abandonTasks = new List <Task>();
                                        foreach (var lockTocken in messagesArray.Select(x => x.SystemProperties.LockToken))
                                        {
                                            abandonTasks.Add(receiver.AbandonAsync(lockTocken));
                                        }
                                        await Task.WhenAll(abandonTasks);
                                    }
                                }
                            }

                            // Close the session and release the session lock
                            if (_isSessionsEnabled)
                            {
                                await receiver.CloseAsync();
                            }
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        // Ignore as we are stopping the host
                    }
                    catch (Exception ex)
                    {
                        // Log another exception
                        _logger.LogError($"An unhandled exception occurred in the message batch receive loop: {ex.ToString()}");
                    }
                }
            }, cancellationToken);
        }