Azure / Azure/azure-functions-host
Clarity on Singleton use with Service Bus binding
- Dominant language
- C#
- Stars
- 2k
- Forks
- 482
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 38
Description
I am using C# to code against Azure Functions version 3 and could use some clarity on the way the Singleton attribute works when scaling out and how that interacts with a Service Bus binding.
All of these tests were done against a function app running in an app service plan set to 2 instances. I'd deploy each to my App Service and fire off a batch of 20 or so messages and check the results in the logs.
For my initial testing I had a simple function like this
[FunctionName("NoSingleton")]
public static async Task Run([ServiceBusTrigger("myqueue", Connection = "ServiceBusConnectionString")]string myQueueItem, ILogger log)
{
log.LogWarning($"NoSingleton: starting");
await Task.Delay(5000);
log.LogWarning("NoSingleton: done waiting");
}
and in the host file I had ServiceBus maxConcurrentCalls set to 1
When I ran this I could see that each of the 2 host instances could process a message in parallel. Within a host, one message was always completed before the next started. This was the behaviour I expected.
For my second test I added the singleton annotation to the function
[Singleton]
Which I believe is equivalent to [Singleton(Mode = SingletonMode.Function)].
When I ran this test, both hosts continued to process messages but not at the same time. When one host completed a message the other one might kick in. There was not longer any parallel processing (i.e. both hosts working on different messages at the same time). Only one host was actively processing at a time.
Is this the expected behaviour for SingletonMode.Function across multiple hosts?
For the third test I updated [Singleton] to [Singleton(Mode = SingletonMode.Listener)].
As expected my function now only ran on a single host. That one host processed each message sequentially.
[EDIT: ** I think I've resolved the maxConcurrentCalls query below. I wasn't aware of the interaction with the prefetchCount property that was set to 1. Setting this to 5 has allowed concurrent message processing **]
Finally I repeated the above tests but with the ServiceBus maxConcurrentCalls set to 5. Each case proceeded as above (i.e. when maxConcurrentCalls was set to 1). All messages were completed before the next was started. I didn't expect this.
So my questions boil down to:
1. Do my initial 3 tests match the expected function behaviour when scaled out to multiple hosts?
2. Why didn't changing maxConcurrentCalls affect the results? How do I enable parallel processing of multiple messages on a host?
Thanks
Alan
Contributor guide
Assessment
This issue has not been assessed yet.