问题
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?
回答1:
I will address your situation by offering that the flow you are proposing is better handled by a LogicApp over a pure function.
It's quite easy to implement the wait/retry/dequeue next pattern in a LogicApp since this type of flow control is exactly what LogicApps was designed for.
回答2:
Although still in preview (not recommended for production code), you could use Durable Functions. If you want to maintain the ability to manipulate objects in code, this is likely your best bet!
(+1 to LogicApp solution too!)
来源:https://stackoverflow.com/questions/49888188/is-there-a-way-i-can-delay-the-retry-for-a-service-bus-message-in-an-azure-funct