示例#1
0
        static async Task ProcessMessagesAsyncDead(Message receivedMessage, CancellationToken token)
        {
            try
            {
                throw new Exception("bibibibibibi");
                ProcessMessage(receivedMessage, "dead-letter");
                await subscriptionDeadLetter.AbandonAsync(receivedMessage.SystemProperties.LockToken);
            }
            catch (Exception)
            {
                await subscriptionDeadLetter.AbandonAsync(receivedMessage.SystemProperties.LockToken);

                Thread.Sleep(TimeSpan.FromSeconds(15));
            }
        }
示例#2
0
 static async Task ProcessMessagesAsyncDead(Message receivedMessage, CancellationToken token)
 {
     try
     {
         ProcessMessage(receivedMessage, "dead-letter");
         await subscriptionDeadLetter.CompleteAsync(receivedMessage.SystemProperties.LockToken);
     }
     catch (Exception)
     {
         await subscriptionDeadLetter.AbandonAsync(receivedMessage.SystemProperties.LockToken);
     }
 }
示例#3
0
        internal static async Task AbandonMessagesAsync(IMessageReceiver messageReceiver, IEnumerable <Message> messages)
        {
            var count = 0;

            foreach (var message in messages)
            {
                await messageReceiver.AbandonAsync(message.SystemProperties.LockToken);

                count++;
            }
            Log($"Abandoned {count} messages");
        }
        protected override void ReceiveEvent(IMessageReceiver client, BrokeredMessage message)
#endif
        {
            try
            {
                Logger.LogDebug(string.Format("An event message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBodyAsString();
                IEvent <TAuthenticationToken> @event = MessageSerialiser.DeserialiseEvent(messageBody);

                CorrelationIdHelper.SetCorrelationId(@event.CorrelationId);
                Logger.LogInfo(string.Format("An event message arrived with the id '{0}' was of type {1}.", message.MessageId, @event.GetType().FullName));

                Type eventType = @event.GetType();

                string targetQueueName = eventType.FullName;

                try
                {
                    object rsn = eventType.GetProperty("Rsn").GetValue(@event, null);
                    targetQueueName = string.Format("{0}.{1}", targetQueueName, rsn);
                }
                catch
                {
                    Logger.LogDebug(string.Format("An event message arrived with the id '{0}' was of type {1} but with no Rsn property.", message.MessageId, eventType));
                    // Do nothing if there is no rsn. Just use @event type name
                }

                CreateQueueAndAttachListenerIfNotExist(targetQueueName);
                EnqueueEvent(targetQueueName, @event);

                // remove the original message from the incoming queue
#if NET452
                message.Complete();
#endif
#if NETSTANDARD2_0
                client.CompleteAsync(message.SystemProperties.LockToken).Wait(1500);
#endif

                Logger.LogDebug(string.Format("An event message arrived and was processed with the id '{0}'.", message.MessageId));
            }
            catch (Exception exception)
            {
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("An event message arrived with the id '{0}' but failed to be process.", message.MessageId), exception: exception);
#if NET452
                message.Abandon();
#endif
#if NETSTANDARD2_0
                client.AbandonAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
            }
        }
示例#5
0
 async Task AbandonMessageIfNeededAsync(Message message)
 {
     try
     {
         if (_messageReceiver.ReceiveMode == ReceiveMode.PeekLock)
         {
             await _messageReceiver.AbandonAsync(message.SystemProperties.LockToken).ConfigureAwait(false);
         }
     }
     catch (Exception exception)
     {
         await RaiseExceptionReceived(exception, ExceptionReceivedEventArgsAction.Abandon).ConfigureAwait(false);
     }
 }
示例#6
0
        private async Task <IList <QueueMessage> > ProcessMessagesInTransaction(string queueName, int quantity)
        {
            IEnumerable <QueueMessage> formattedMessages = new List <QueueMessage>();
            var messages = await _messageReceiver.ReceiveAsync(quantity, TimeSpan.FromSeconds(60));

            try
            {
                if (messages == null)
                {
                    return(null);
                }

                formattedMessages = messages.Select(message => message.Convert(_userService.GetUserId(), queueName));

                await AddMessagesToDatabase(formattedMessages);

                await _messageReceiver.CompleteAsync(messages.Select(message => message.GetLockToken()));
            }
            catch (CosmosBatchInsertException ex)
            {
                await HandleBatchCreationFailure(formattedMessages, ex.StatusCode);

                _logger.LogError("Failed to create messages with error: {0}, exception: {1}", ex.StatusCode.ToString(),
                                 ex.ToString());
            }
            catch (Exception ex)
            {
                _logger.LogError("Failed to receive messages: {0}", ex.ToString());

                foreach (var message in formattedMessages)
                {
                    await _messageReceiver.AbandonAsync(message.OriginalMessage.GetLockToken());
                }
            }

            return(formattedMessages.ToList());
        }
        static async Task ListenMessageAsync()
        {
            try
            {
                Console.WriteLine("Receiving message...");
                var message = await _queueReceiver.ReceiveAsync(TimeSpan.FromSeconds(5));

                if (message != null)
                {
                    lock (Console.Out)
                    {
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.WriteLine(
                            "\t\t\t\tMessage received: \n\t\t\t\t\t\tMessageId = {0}, \n\t\t\t\t\t\tSequenceNumber = {1}, \n\t\t\t\t\t\tEnqueuedTimeUtc = {2}," +
                            "\n\t\t\t\t\t\tExpiresAtUtc = {5}, \n\t\t\t\t\t\tContentType = \"{3}\", \n\t\t\t\t\t\tSize = {4},  \n\t\t\t\t\t\tContent: [ ], \n\t\t\t\t\t\tDelivery Count: {6}",
                            message.MessageId,
                            message.SystemProperties.SequenceNumber,
                            message.SystemProperties.EnqueuedTimeUtc,
                            message.ContentType,
                            message.Size,
                            message.ExpiresAtUtc,
                            message.SystemProperties.DeliveryCount);
                        Console.ResetColor();
                    }
                    //await _queueReceiver.CompleteAsync(message.SystemProperties.LockToken);
                    var properties = new Dictionary <string, object>();
                    var newDate    = DateTime.UtcNow + TimeSpan.FromSeconds(10);
                    //properties.Add("ScheduledEnqueueTimeUtc", newDate);
                    properties.Add("MessageId", message.MessageId + 5);
                    await _queueReceiver.AbandonAsync(message.SystemProperties.LockToken, properties);
                }
                else
                {
                    Console.WriteLine($"There is no message in the queue");
                }
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"{e.Message}");
                _logger.TrackException(e);
                Console.ResetColor();
            }
        }
示例#8
0
        private async Task HandleMessage(Message message, CancellationToken cancellationToken)
        {
            //Console.WriteLine($"Handled message id {message.MessageId}, diagnostic id {message.UserProperties["Diagnostic-Id"]}, enclosed type {message.UserProperties["EnclosedType"]}");
            try
            {
                await messageHandler.HandleMessage(message, cancellationToken);

                await messageReceiver.CompleteAsync(message.SystemProperties.LockToken);
            }
            catch (Exception ex)
            {
                Dictionary <string, object> abandonReasons = new Dictionary <string, object>
                {
                    { "Exception.Message", ex.Message },
                    { "Exception.StackTrace", ex.ToString() }
                };
                await messageReceiver.AbandonAsync(message.SystemProperties.LockToken, abandonReasons);
            }
        }
示例#9
0
        public async Task ReceiveMessageAsync(IMessageReceiver receiver, Message message, CancellationToken cancellationToken)
        {
            Exception receiveEx = null;

            try
            {
                cancellationToken.ThrowIfCancellationRequested();
                Console.WriteLine("Received MessageId=[{0}] MessageBody=[{1}]", message.MessageId, Encoding.UTF8.GetString(message.Body));
                await receiver.CompleteAsync(message.SystemProperties.LockToken);
            }
            catch (Exception ex)
            {
                receiveEx = ex;
                Console.WriteLine("Exception ocurred during ReceiveMessageAsync() Message=[{0}]", ex.Message);
            }

            if (receiveEx != null)
            {
                await receiver.AbandonAsync(message.SystemProperties.LockToken);
            }
        }
示例#10
0
        protected async Task <bool> HandleMessageOutcome(
            Message message,
            MessageHandlingResult result)
        {
            var isSuccessful       = result.Result == MessageHandlingResult.HandlingResult.Completed;
            var shouldAutoComplete = _endpointHandlingConfig.AutoComplete || _receiver.IsClosedOrClosing;

            if (shouldAutoComplete)
            {
                return(isSuccessful);
            }

            try
            {
                switch (result.Result)
                {
                case MessageHandlingResult.HandlingResult.Completed:
                    await _receiver.CompleteAsync(message.SystemProperties.LockToken).ConfigureAwait(false);

                    break;

                case MessageHandlingResult.HandlingResult.DeadLettered:
                case MessageHandlingResult.HandlingResult.UnrecognisedMessageType:
                    await _receiver.DeadLetterAsync(message.SystemProperties.LockToken, result.AdditionalProperties).ConfigureAwait(false);

                    break;

                case MessageHandlingResult.HandlingResult.Abandoned:
                    await _receiver.AbandonAsync(message.SystemProperties.LockToken, result.AdditionalProperties).ConfigureAwait(false);

                    break;
                }
            }
            catch (MessageLockLostException ex)
            {
                _logger.LogError(LogEventIds.ListenerException, ex, $"MessageLockLostException in {_name}>");
            }
            return(isSuccessful);
        }
示例#11
0
        protected virtual async Task ReceiveInitiativeStatusChanged(Message msg, CancellationToken token, Func <InitiativeStatusChangedEventArgs, CancellationToken, Task> handler)
        {
            if (msg == null)
            {
                throw new ArgumentNullException("msg");
            }
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }

            if (await EnsureMessageLabel(msg, InitiativeMessageSender.STATUS_CHANGED))
            {
                _logger.Information("Received StatusChanged message. Getting initiative");

                var idea = await GetMessageInitiative(msg);

                if (idea.WasMessageDeadLettered)
                {
                    return;
                }

                try
                {
                    await handler(new InitiativeStatusChangedEventArgs()
                    {
                        Initiative = idea.Item
                    }, token);

                    await _messageReceiver.CompleteAsync(msg.LockToken);
                }
                catch (Exception err)
                {
                    _logger.Error(err, "InitiativeStatusChanged handler threw the following error, abandoning message for future processing: {ErrorMessage}", err.Message);
                    await _messageReceiver.AbandonAsync(msg.LockToken);
                }
            }
        }
 public override Task AbandonAsync(
     IQueueMessage message,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(_messageReceiver.AbandonAsync(message.LeaseId));
 }
示例#13
0
        /// <summary>
        /// dispatch message by its label
        /// </summary>
        /// <param name="message"></param>
        /// <param name="receiver"></param>
        /// <returns></returns>
        private async Task DispatchMessage(Message message, IMessageReceiver receiver)
        {
            if (message.Label == null || !setting.messageHandlers.ContainsKey(message.Label))
            {
                // don't have to wait the call
                /*await*/
                receiver.AbandonAsync(message.SystemProperties.LockToken);
                return;
            }

            var handlers = setting.messageHandlers[message.Label];

            if (handlers.Count == 0)
            {
                // don't have to wait the call
                /*await*/
                receiver.CompleteAsync(message.SystemProperties.LockToken);
                return;
            }

            try
            {
                var hId  = -1;
                var pack = new HandlerPack();
                pack.stationId = stationId;
                pack.receiver  = receiver;
                pack.message   = message;
                pack.terminate = () =>
                {
                    hId = handlers.Count;
                };
                pack.next = async() =>
                {
                    hId++;
                    if (hId < handlers.Count)
                    {
                        var handler = handlers[hId];
                        await handler.Invoke(pack);
                    }
                };

                // start handler function chain
                while (hId < handlers.Count)
                {
                    try
                    {
                        await pack.next();
                    }
                    catch (System.Exception e)
                    {
                        Console.WriteLine("============");
                        Console.WriteLine(e.ToString());

                        receiver.DeadLetterAsync(message.SystemProperties.LockToken);
                        break;
                    }
                }
                return;
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            // for any uncatched exception
            try
            {
                receiver.AbandonAsync(message.SystemProperties.LockToken);
            }
            catch (System.Exception e)
            {
                throw;
            }
        }
示例#14
0
 public async Task abandonAsync()
 {
     terminate.Invoke();
     /*await*/
     receiver.AbandonAsync(message.SystemProperties.LockToken);
 }
        internal void StartMessageBatchReceiver(CancellationToken cancellationToken)
        {
            SessionClient    sessionClient = null;
            IMessageReceiver receiver      = null;

            if (_isSessionsEnabled)
            {
                sessionClient = _sessionClient.Value;
            }
            else
            {
                receiver = Receiver;
            }

            Task.Run(async() =>
            {
                while (true)
                {
                    try
                    {
                        if (!_started || cancellationToken.IsCancellationRequested)
                        {
                            _logger.LogInformation("Message processing has been stopped or cancelled");
                            return;
                        }

                        if (_isSessionsEnabled && (receiver == null || receiver.IsClosedOrClosing))
                        {
                            try
                            {
                                receiver = await sessionClient.AcceptMessageSessionAsync();
                                receiver.PrefetchCount = _serviceBusOptions.PrefetchCount;
                            }
                            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
                                {
                                    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);
                                }
                            }
                        }
                        else
                        {
                            // Close the session and release the session lock after draining all messages for the accepted session.
                            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);

                        if (_isSessionsEnabled && receiver != null)
                        {
                            // Attempt to close the session and release session lock to accept a new session on the next loop iteration
                            try
                            {
                                await receiver.CloseAsync();
                            }
                            catch
                            {
                                // Best effort
                                receiver = null;
                            }
                        }
                    }
                }
            }, cancellationToken);
        }
示例#16
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);
        }
示例#17
0
 public Task Abandon(string lockToken)
 => messageReceiver.AbandonAsync(lockToken);
示例#18
0
 public void Abandon(string lockToken)
 {
     _messageReceiver.AbandonAsync(lockToken).Wait();
 }