3

I have an Azure Function, with a queue trigger. The function must proces one queue message each time, one by one, sequentially. This is important, since the function uses an external OAuth API, with various limitions on requesting new access and refresh tokens.

In order to process the queue sequentially, I've the following settings:

host.json

"queues": {
  "batchSize": 1,
  "newBatchThreshold": 0
}

Application settings

FUNCTIONS_WORKER_PROCESS_COUNT = 1
WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT = 1

Despite these settings, it happens sometimes that the function gets triggered multiple times. Not in my tests, where I dump a lot of messages in the queue, but when the functions is live.

I've dived into the Application Insights Log, and I found that the function gets restarted a lot during the day, and when it restarts, it sometimes start the functions twice.

For example:

Log

Two instances are started. I'm guessing this causes my double triggers from the queue.

How can I make sure the function is triggered once?

TJ_
  • 629
  • 6
  • 12
  • Message are locked (peek-lock) during processing so this can't happen, even if multiple instances are involved. *it happens sometimes that the function gets triggered multiple time* -> are you sure the exact same message is processed twice? Could only happen if it has not been completed or the processing has faulted the first time. – Peter Bons Sep 07 '22 at 14:35
  • I'm sorry, it's not the same message that's processed twice. There are two messages that are proccessed in parallel. – TJ_ Sep 07 '22 at 14:38
  • Ah my bad, misread the question. – Peter Bons Sep 07 '22 at 14:41

1 Answers1

2

I believe the only way to make it even more secure that only one message will be executed at the same time is to use sessions. Give every message the same sessionId to guarantee your desired behavior. Be aware that some things like deadlettering will behave differently if you switch to sessions.

You can also use the [Singleton] attribute if that fits your function app. It should also work, but can incur additional costs when you use the consumption plan. So you need to validate how it affects costs given your workload.

See also my other answer here: azure servicebus maxConcurrentCalls totally ignored

Alex AIT
  • 17,361
  • 3
  • 36
  • 73
  • Thanks! Sessions are only available for Service Bus Queues right? Currently I'm using Azure Storage Queues. I'll try the [Singleon] attribute. Q: Why could it result in extra costs? – TJ_ Sep 12 '22 at 13:45
  • 1
    I missed the part about the storage queue. Regarding costs: Jeff Hollan explains it a bit on GitHub (https://github.com/Azure/azure-functions-host/issues/912#issuecomment-419608830). There is also a bit more about handling storage queues. But it is quite a bit to read through. – Alex AIT Sep 12 '22 at 14:46
  • 1
    After more than 2 weeks, it never fired double instances and the queue is processed perfectly, one-by-one. So, the [Singleton] works in my case. Since the possible 'wait' for a incoming queue message is never too long, the possible extra costs are very low. Too bad the MS docs aren't complete; the settings on batchsize and concurrency aren't sufficient. Thanks @Alex AIT! – TJ_ Sep 22 '22 at 10:23