4

I am attempting to convert my v1 function to a v2 function, but I cannot find a replacement for deferring a message.

In V1 of Azure Functions it was a method on the BrokeredMesage called .DeferAsync(). In V2 there is no longer a BrokeredMessage but just a Microsoft.Azure.ServiceBus.Message and this does not contain the method of .DeferAsync().

According to the docs:

The API is BrokeredMessage.Defer or BrokeredMessage.DeferAsync in the .NET Framework client, MessageReceiver.DeferAsync in the .NET Standard client, and mesageReceiver.defer or messageReceiver.deferSync in the Java client.

But how can I get access to the MessageReciever? Here is an example of my function:

[FunctionName("MyFunction")]
public static void Run([ServiceBusTrigger("topic", "subscription", Connection = "AzureServiceBusPrimary")]Message message, ILogger log)
{
    //Code
}

So does anyone know how to defer a V2 Message that is triggered from the Azure Service Bus?

Jamie Rees
  • 7,973
  • 2
  • 45
  • 83

1 Answers1

3

As you mention, the new message receiver offers an async defer method and you can add this to your function by using the following code:

[FunctionName("MyFunction")]
public static async Task Run([ServiceBusTrigger("topic", "subscription", Connection = "AzureServiceBusPrimary")]Message message, string lockToken, MessageReceiver messageReceiver, ILogger log)
{
    //Your function logic
    await messageReceiver.DeferAsync(lockToken);
}
Armando Bracho
  • 659
  • 5
  • 21
  • 2
    Where did you find the documentation for this? – Jamie Rees Jun 04 '19 at 08:28
  • Sorry i could not provide the documentation source as i found this when i was implementing a custom retry logic for my v2 functions and saw an implementation code using it. I have not found a documentation source that will detail this but if someone has please share on the comments. – Armando Bracho Jun 04 '19 at 08:45
  • 1
    No documentation as if today, but it's injected by the Functions SDK in addition to [metadata](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus#trigger---message-metadata) that is diviners. I've captured it my blog post [here](https://weblogs.asp.net/sfeldman/transactional-messaging-with-azure-functions-and-service-bus). Audio, there's an [issue](https://github.com/MicrosoftDocs/azure-docs/issues/32126) to add it to the documentation. – Sean Feldman Jun 04 '19 at 12:30
  • The Functions team is working on documentation for the Service Bus trigger to clarify that you can bind to the `MessageReceiver` class. From there, the `DeferAsync()` method is documented as part of the SDK documentation. The issue for this documentation improvement is here: https://github.com/MicrosoftDocs/azure-docs/issues/32126. – Connor McMahon Jun 04 '19 at 21:16
  • For some reason this does not work on my side. I get an error that the message is already completed so the lockToken is already expired. See my post: [Defer message in azure function V2: The lock supplied is invalid](https://stackoverflow.com/questions/63179056/defer-message-in-azure-function-v2-the-lock-supplied-is-invalid) – hwcverwe Jul 30 '20 at 18:25
  • What will Defer do? Will the message come back again in the Azure Function after lets say x minutes where x can be configured? Thanks. – user1685304 Jul 20 '21 at 07:21
  • @user1685304 No, what you are describing is what the scheduling functionality is for, a great article about this topic can be found here https://www.pmichaels.net/2021/02/27/deferred-messages-in-azure-service-bus/ TL;DR: when you schedule a message, you’re telling the Service Bus to deliver that message at a time of your choosing, when you defer a message, you telling the Service Bus to hang onto a message that has been sent, until such time as you’re ready to receive it. – Armando Bracho Jul 21 '21 at 13:09