Reputation: 1054
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
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
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