简体   繁体   中英

Azure function with Servicebus how to not mark message as complete

I have an Azure function that listens to messages in an Azure Servicebus queue. When it receives the messages it marks them as complete and they are no longer in the queue. Is there a way to mark them as only when a long process completes ? Or un mark them as complete if it fails ?

My function calls an Api and I would like the message to not be marked as complete till the Api responds back with a success code.

The message will be marked as complete after the function execution is complete.

The easiest way to abort the message is to throw an exception from your function, eg when your API responds with error status code. In this case, the message will be put back to the queue and the function will be re-tried (up until the max number of retries configured for this Service Bus queue).

When it receives the messages it marks them as complete and they are no longer in the queue.

By default, the Functions runtime actually doesn't mark a message as complete until your function returns successfully . As mentioned in the accepted answer, throwing an exception (in your case, if the API being called returns with an unfavorable response) would abandon the message and prevent it from being marked as complete.

For a lot more control over when your message is completed, abandoned, etc, you can consume your message as a BrokeredMessage type as mentioned previously. This class directly supports the methods you'd need to control what happens to your message. Note, the service bus trigger documentation mentions that BrokeredMessage should be used for Azure Functions version 1.* . If you're using version 2.* , you should consume your message as a Message type instead.

One pain-point of using Message is that, unlike BrokeredMessage , it doesn't directly have methods to let you control when a message is completed, etc. To achieve this, we can bind a MessageReceiver parameter to our function.

To show how this works, here's an dead-lettering example of using Message along with MessageReceiver :

[FunctionName("SOExampleFunction"]
public static async Task ProcessMessage(
    [ServiceBusTrigger("myqueue")] Message message,
    MessageReceiver messageReceiver)
{
    . . .

    await messageReceiver.DeadLetterAsync(message.SystemProperties.LockToken);

    . . .
}

While using this approach, make sure you have the "autoComplete" service bus setting set to false in your host.json. Eg:

{
  "version": "2.0",
  "extensions": {
    "serviceBus": {
      "messageHandlerOptions": {
        "autoComplete": false
      }
    }
  }
}

As an alternative to the accepted answer, if you set the signature of your function to accept accept a BrokeredMessage then you can manually deadletter a message.

[FunctionName("MyFunctionName")]
public async static Task Run([ServiceBusTrigger("myqueue", AccessRights.Manage)]BrokeredMessage brokeredMessage, TraceWriter log) {

    // This will immediately deadletter the message.
    await brokeredMessage.DeadLetterAsync("My reason for deadlettering", "Some description that further explains...");

    return;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM