예제 #1
0
        async Task ProcessMessage(Message receivedMessage, CancellationToken token)
        {
            try
            {
                await maxConcurrencySempahore.WaitAsync(token).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                // shutting down, semaphore doesn't need to be released because it was never acquired
                return;
            }

            try
            {
                IncomingMessage  incomingMessage  = null;
                TransportMessage transportMessage = null;

                var isPoisonMessage = false;
                try
                {
                    transportMessage = JsonConvert.DeserializeObject <TransportMessage>(receivedMessage.Body);

                    incomingMessage = await transportMessage.ToIncomingMessage(s3Client, configuration, token).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    // shutting down
                    return;
                }
                catch (Exception ex)
                {
                    // Can't deserialize. This is a poison message
                    Logger.Warn($"Treating message with SQS Message Id {receivedMessage.MessageId} as a poison message due to exception {ex}. Moving to error queue.");
                    isPoisonMessage = true;
                }

                if (incomingMessage == null || transportMessage == null)
                {
                    Logger.Warn($"Treating message with SQS Message Id {receivedMessage.MessageId} as a poison message because it could not be converted to an IncomingMessage. Moving to error queue.");
                    isPoisonMessage = true;
                }

                if (isPoisonMessage)
                {
                    await MovePoisonMessageToErrorQueue(receivedMessage).ConfigureAwait(false);

                    return;
                }

                if (!IsMessageExpired(receivedMessage, incomingMessage))
                {
                    await ProcessMessageWithInMemoryRetries(incomingMessage, token).ConfigureAwait(false);
                }

                // Always delete the message from the queue.
                // If processing failed, the onError handler will have moved the message
                // to a retry queue.
                await DeleteMessage(receivedMessage, transportMessage, incomingMessage, token).ConfigureAwait(false);
            }
            finally
            {
                maxConcurrencySempahore.Release();
            }
        }