Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way I can delay the retry for a service bus message in an Azure function?

I have a function which pulls messages off a subscription, and forwards them to an HTTP endpoint. If the endpoint is unavailable, an exception is thrown. When this happens, I would like to delay the next attempt of that specific message for a certain amount of time, e.g. 15 minutes. So far, I have found the following solutions:

  • Catch the exception, sleep, then throw. This is a terrible solution, as I will be charged for CPU usage while it is sleeping, and it will affect the throughput of the function.
  • Catch the exception, clone the message, set the ScheduledEnqueueTimeUtc property and add it back to the queue. This is a nicer way, but it resets the delivery count, so an actual problem will never be dead-lettered, and it is resent to all subscriptions, when only one subscriber failed to process it.
  • Catch the exception, and place the message on a storage queue instead. This means maintaining a storage queue to match each subscription, and having two functions instead of one.

What I would ideally like to happen is to catch the exception, and exit the function without releasing the lock on the message. That way, as soon as the lock expires the message will be retried again. However, it seems that after completing successfully, the function calls Complete() on the message, and after an exception is thrown, the function calls Abandon() on the message. Is it possible to bypass this, or to achieve the delay some other way?

like image 686
Andrew Williamson Avatar asked Oct 20 '25 09:10

Andrew Williamson


1 Answers

This is now supported natively through retry policies, which were added to Azure Functions around November 2020 (preview). You can configure the retry policy as fixed-delay or exponential-backoff.

[FunctionName("MyFunction")]
[FixedDelayRetry(10, "00:15:00")]   // retries with a 15-minute delay
public static void Run(
    [ServiceBusTrigger("MyTopic", "MySubscription", Connection = "ServiceBusConnection")] string myQueueItem) 
{
    // Forward message to HTTP endpoint, throwing exception if endpoint unavailable
}
like image 70
Douglas Avatar answered Oct 21 '25 21:10

Douglas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!