Azure Service Bus and App Service function re-deliveries

Elio Rodrigues (erodrigu) 21 Reputation points
2020-06-29T20:13:34.32+00:00

Hello,

On our company Azure portal we have a service bus with a topic and a couple subscriptions on it. I created an App Service with a simple function to test how to integrate with the Service bus using a topic trigger.

The happy path of the message works perfectly the message is processed and it gets completed and removed from the message subscription queue.

Now we have a second use case where for some reason a message doesn't work as we expect, we are throwing an exception and the system catches this exception in order to mark the message as abandoned and then it tries re-delivering the message again.

The thing is that on our topic subscription we have that a message can be delivered up to 100 times before it gets sent to the dead-letter queue.

Our test service bus-function tries to deliver the message every 10 MS or as soon as the function throws the exception. The system goes and increases the delivery count of the message and calls the function AGAIN. A 100 deliveries of a single message is fired in seconds and the message is sent to the dead-letter queue almost immediately.

The thing is that we would like to have to sort of "delay" for the re-deliveries of messages. Something like message 1 arrives, it fails increase message counter and wait 1 minute or so before delivering the same message to the function a second time.

I have been investigating for the past week and there seems no way to delay the deliveries of messages? or is there a way?

The only option I could find that might "work" but not ideal is to use a "new" message with a scheduled time? and mark the current message as completed?.

Azure Service Bus
Azure Service Bus
An Azure service that provides cloud messaging as a service and hybrid integration.
542 questions
Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,231 questions
0 comments No comments
{count} votes

Accepted answer
  1. MayankBargali-MSFT 68,396 Reputation points
    2020-06-30T05:09:42.563+00:00

    Welcome to Microsoft Q&A! Thanks for posting the question.

    There is no out of box feature that will delay your re-deliveries of the message. There can be two workarounds for this scenario

    1. You can submit the message again with EnqueueTimeUtc property, message property (matching the specific subscription rule), and mark the existing message as completed. If you are not specifying the message property matching the specific subscription rule then the message will be delivered to all the subscriptions under that topic causing duplicate messages in other subscriptions.
      1. If you are sure that for the specific use case you want to redelivery that message after 1 min then you can leverage the lock duration property at the subscription level (default 30 sec and max 5 min). When you peek-lock the message and according to use case you want to redeliver it after 1 min (setting lock duration as 1 min) then you should not call complete, deferred, or abandoned on that message. Once the lock duration expires the message will be visible again for the client to be consumed.

    I hope this helps. Do let us know if you any further queries.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Elio Rodrigues (erodrigu) 21 Reputation points
    2020-06-30T21:35:08.3+00:00

    Hello @MayankBargali-MSFT thanks for the response. How can I specify the subscription where I want the message to go to?

    The output of an azure function doesn't allow a subscription to be set on it. Below is a sample of the code I have.

    [FunctionName("FunctionTest")]  
    [return: ServiceBus("Topic", Connection = "connection")]  
    public static Message Run([ServiceBusTrigger("Topic", "subscription", Connection = "connection")]Message mySbMsg,  
        ILogger log)  
    {  
        try  
        {  
            log.LogInformation($"C# ServiceBus topic trigger function processed message: {System.Text.Encoding.UTF8.GetString(mySbMsg.Body)}");  
            throw new Exception("error");  
        }  
        catch(Exception)  
        {  
            var scheduledmessage = new Message(mySbMsg.Body);  
            scheduledmessage.ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddSeconds(30);  
            return scheduledmessage;  
        }  
    }