Dr. Rahul Jha
Dr. Rahul Jha

Reputation: 1054

Azure function service bus trigger running multiple times

I have added a project in my visual studio solution which is a service bus topic trigger function. I am running application with default code but facing problem. Whenever I am adding message to service bus topic, my trigger executes 5-6 times per message and last it get following error.

Error

The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue.

My code:

[FunctionName("TopicFunction1")]
    public static void Run(
        [ServiceBusTrigger("myservicebustopicname", "subscriptionname", Connection = "ServiceBus_NS_ConnectionString")]string message,
        Int32 deliveryCount,
        ILogger log)
    {
        log.LogInformation($"ServiceBus topic trigger function processed message: {message}");
    }

Delivery count is reaching to 5-6.

I checked multiple questions related to this issue and they are not helpful. One example is below. Azure Function App Azure Service Bus trigger triggers twice

Please help on this.

Upvotes: 5

Views: 8050

Answers (2)

sveinungf
sveinungf

Reputation: 1081

If you have "autoComplete": false in your host.json file, then the messages will be processed, but will not automatically disappear from the topic subscription. Like in this host.json file:

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

Removing autoComplete or setting it to true should make the function remove successfully processed messages from the topic subscription.

If you need more control and can't use the autoComplete feature, then you can explicitly complete messages by adding a MessageReceiver parameter, and call CompleteAsync for the Message object like this:

[FunctionName("TopicFunction1")]
public static async Task Run(
    [ServiceBusTrigger("myservicebustopicname", "subscriptionname", Connection = "ServiceBus_NS_ConnectionString")]Message message,
    MessageReceiver messageReceiver,
    ILogger log)
{
    log.LogInformation($"ServiceBus topic trigger function processed message: {message}");
    await messageReceiver.CompleteAsync(message.GetLockToken());
}

Upvotes: 1

Murray Foxcroft
Murray Foxcroft

Reputation: 13745

Some things to check. All references are to the documentation.

Make sure it is the same message every time and you are not receiving multiple by logging out the message ID.

[FunctionName("ServiceBusQueueTriggerCSharp")]                    
public static void Run(
    [ServiceBusTrigger("myqueue", Connection = "ServiceBusConnection")] 
    string myQueueItem,
    Int32 deliveryCount,
    DateTime enqueuedTimeUtc,
    string messageId,
    ILogger log)
{
    log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
    log.LogInformation($"EnqueuedTimeUtc={enqueuedTimeUtc}");
    log.LogInformation($"DeliveryCount={deliveryCount}");
    log.LogInformation($"MessageId={messageId}");
}

If your function is throwing any exceptions the message will get retried but this does not seem to be the case.

Lastly, and most likely, if you have two function apps or deployments and they are pointed at the same queue, then they may be competing with each other, copied below is how the messages are processed. You could be getting a race condition. Make sure you only have one instance running and no other code is competing on the queue.

PeekLock behavior The Functions runtime receives a message in PeekLock mode. It calls Complete on the message if the function finishes successfully, or calls Abandon if the function fails. If the function runs longer than the PeekLock timeout, the lock is automatically renewed as long as the function is running.

The maxAutoRenewDuration is configurable in host.json, which maps to OnMessageOptions.MaxAutoRenewDuration. The maximum allowed for this setting is 5 minutes according to the Service Bus documentation, whereas you can increase the Functions time limit from the default of 5 minutes to 10 minutes. For Service Bus functions you wouldn’t want to do that then, because you’d exceed the Service Bus renewal limit.

Upvotes: 2

Related Questions