Search code examples
azureazure-functionsazure-servicebus-queuesretrypolicy

How to re-queue message with updated information while working with Azure Service Bus Queue Function?


While working with Azure Service Bus Queue function, we know that whenever there is an exception, azure function will perform a default retry policy (max count = 10), what we would like to do is to have our message with a property called retryCount, so when exception generates, we would increase the retryCount += 1, and also add the current exception to our message, then next time while function performs the retry, we could know this is the xth time that it comes in along with x records of exceptions. We know that the Message object had a read-only property called deliveryCount, however, we cannot bind our addition information or figure out what would be the reason of last failed delivery from the Message object.

However, after we tried to implement our idea, we found that whenever the function performs the retry, it always reload the initial message from the queue, not with our updated message. Is there any way to let it retry with updated message without force to re-send the updated back to the current queue?

In addition, how could we customize the current retry logic, for example, decrease the max retry count from 10 to 1 and use Polly to handle some scenario inside the function?


Solution

  • You don't really need a custom retryCount as the message already contains a system property called DeliveryCount that tracks the number of delivery (read processing) attempts. If you need to store some additional metadata between the retries, you would need to abandon your message. With Functions v2, to abandon a message you will need to use the message receiver used to receive the message.

    public static async Task ProcessMessage([ServiceBusTrigger("myqueue")] string message,
    int deliveryCount,
    MessageReceiver messageReceiver,
    string lockToken)
    {
      //
      await messageReceiver.AbandonAsync(lockToken, 
                new Dictionary<string, object> { { "Reason", "Blah" });
    }
    

    Note that to ensure Azure Functions continues to process the message you will need to throw an exception. Otherwise, Functions by default assumes the message was processed successfully and will attempt to complete the message.