Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Azure webjob processing same message multiple times concurrently

I have an Azure WebJob project, that I am running locally on my dev machine. It is listening to an Azure Service Bus message queue. Nothing going on like Topics, just the most basic message queue.

It is receiving/processing the same message multiple times, launching twice immediately when the message is received, then intermittently whilst the message is being processed.

Questions:

  • How come I am receiving the same message multiple times instantly? It seems that it's re-fetching before a PeekLock is applied?
  • How come the message is being re-received even though it is still being processed? Can I set the PeekLock duration, or somehow lock the message to only be processed once
  • How can I ensure that each message on the queue is only processed once?
  • I want to be able to process multiple messages at once, just not the same message multiple times, so setting MaxConcurrentCalls to 1 does not seem to be my answer, or am I misunderstanding that property?

I am using an async function, simple injector and a custom JobActivator, so instead of a static void method, my Function signature is:

public async Task ProcessQueueMessage([ServiceBusTrigger("AnyQueue")] MediaEncoderQueueItem message, TextWriter log) {...}

Inside the job, it is moving some files around on a blob service, and calling (and waiting for) a media encoder from media services. So, whilst the web job itself is not doing a lot of processing, it takes quite a long time (15 minutes, for some files).

The app is launching, and when I post a message to the queue, it responds. However, it is receiving the message multiple times as soon as the message is received:

Executing: 'Functions.ProcessQueueMessage' - Reason: 'New ServiceBus message detected on 'MyQueue'.'
Executing: 'Functions.ProcessQueueMessage' - Reason: 'New ServiceBus message detected on 'MyQueue'.'

Additionally, whilst the task is running (and I see output from the Media Service functionality), it will get another "copy" from the queue.

finally after the task has completed, it's still intermittently processing the same message.

like image 608
AndrewP Avatar asked Aug 03 '16 11:08

AndrewP


People also ask

How do I run a webjob in Azure App service?

To run the WebJob, right-click its name in the list and click Run. In the Azure portal, go to the App Service page of your App Service web app, API app, or mobile app. Select WebJobs. In the WebJobs page, select Add. Use the Add WebJob settings as specified in the table.

Can I run background tasks in the Azure App service?

You can run background tasks in the Azure App Service. If instead of the Azure App Service you are using Visual Studio 2019 to develop and deploy WebJobs, see Deploy WebJobs using Visual Studio. WebJobs is a feature of Azure App Service that enables you to run a program or script in the same instance as a web app, API app, or mobile app.

How do I enable always on for my Azure webjobs?

If you set your web app to run continuous or scheduled (timer-trigger) WebJobs, enable the Always on setting on your web app's Azure Configuration page to ensure that the WebJobs run reliably. This feature is available only in the Basic, Standard, and Premium pricing tiers. Supported file types for scripts or programs

How do I connect a queue to a webjob function?

Use the "Add Connected Services" dialog box in Visual Studio to attach an Azure Storage Account with a Queue that your WebJob function will watch. When a message is posted on the Queue, your function will get called.


1 Answers

I suspect what's happening is the following: Maximum DurationLock can be 5 minutes. If processing of the message is done under 5 minutes, message is marked as completed and removed from the broker. Otherwise, message will re-appear if processing takes longer than 5 minutes (we lost the lock on the message) and will be consumed again. You could verify that by looking at the DeliveryCount of your message.

To resolve that, you could renew message lock just before it's about to expire using BrokeredMessage.RenewLockAsync().

like image 99
Sean Feldman Avatar answered Sep 22 '22 03:09

Sean Feldman