azure-functions-host
azure-functions-host copied to clipboard
Add Singleton support for Functions to ensure only one function running at a time
We should discuss whether we want to bring this functionality forward for Functions. However, it will be relatively simple for us to do - we just need to expose new properties via function.json for function level singletons. See here for singleton doc.
In addition to Function level singleton support, we might also consider supporting Listener level Singleton as well.
When we do this, we should make sure it works across multiple languages (not just C#)
Customer wants this feature: https://social.msdn.microsoft.com/Forums/en-US/4f21e730-e4f3-4f5f-a408-56e23283fb92/run-azure-function-as-singleton-listener-with-node-js?forum=AzureFunctions
We would love to have that. Let us specify singleton in different scopes just like in web jobs.
Thanks @vladkosarev. This issue has been on the back burner, since not many people have been asking for it yet. What specifically is your scenario?
Being able to process messages from multiple queues in series as long as they affect the same entity. So if we have two queues and both of them will affect Order/1 (which is encoded in queue messages) we want the two different functions to kick in in series and process messages from those two queues one by one instead of in parallel. The idea here is having serialized access to data storage for a particular entity.
@vladkosarev sounds like actor model. I would love to see how efficient it's with using scoped singleton and Azure functions. Another option is to use Service Fabric, but it's huge piece of infrastructure to be handled. Prefer to start with something as lightweight as Azure functions
That is exactly what I'm trying to achieve. Actor-like model using Azure functions. Now that they announced that functions will support serverless framework this might not be as important but I'd still like this ability in the 'raw'. Service Fabric is great but it's still not serverless. I want to pay for compute resources not for VMs. Consumption functions + actors on top is my path to nirvana. Obviously you can't have in memory state, etc but it would still be a good start to the path of properly infinitely scalable architecture.
@lindydonna Hey I'm just wondering if there are any updates in regards to when we might expect support for singleton functionality with Azure Functions. Based on the conversation here it seemed like it might be low hanging fruit. It would be extremely helpful to be able to specify singleton behavior in function.json
I have use case where this would very helpful. I have long running background processing tasks which are triggered via a storage queue. In order to prevent spikes in the database load, I need to ensure that that there is not more than one queue item being processed at a time.
My current solution is to use a timer trigger with a short interval to manually poll the queue, but a singleton flag for queue triggers would be a much tidier option.
Yes, I didn't know what this was from the title. Perhaps rename the report to something more descriptive.
My case is just about the same. Would like to guarantee only one queue function running at a time. NOTE with the current time limitations we cannot just wait.
-thanks Donna -e
Seems like you could support locking on your own - you just need shared storage backing it - SQL Azure, Azure Blob/Table/Queue, Redis, etc. Would be great just to add a [SingletonAttribute]
to our Azure Functions like webjobs has. host.json
has configurable options for singletons, but I don't know if it supports Azure functions (AF) versus Web Jobs. Could just add an environment key which has the storage connection string etc, and assign it in our host.json
.
@lindydonna any updates on a timeline for this feature?
I have a couple of Projects where I would like to switch from WebJobs to Azure Functions as well as some new Projects that need serial processing for queues, which require this functionality.
From my understanding of the way this works for WebJobs is a lock blob with a lease in the storage accounts. Azure Functions appear to already use this mechanism for the Timer-Trigger.
@alohaninja Supporting locking on our own is not trivial. e.g. In a Queue-Trigger Function you could only throw an exception so that the message is put back in the queue, this may however lead to the message being marked as poison and therefore lost if you cannot process it in time. Additionaly the Function will still be invoked leading to extra costs.
According to this issue there is currently no support for the Singleton Attribute in Azure Functions and the host.json options are therefore moot.
Possible Workarounds:
- Timer-Trigger Functions appear to run as Singletons. They produce a blob in the storage account under "locks/" and create a lease. This requires implementing the input on your own.
- ServiceBus-Trigger Functions with serviceBus.maxConcurrentCalls to 1 in host.json. This is however a global setting and I would like use this on a per function basis.
@lindydonna is it possible to confirm that Timer-Trigger Functions run as singletons?
@aboersch - came here because we are using Timer-Trigger functions and they can run simultaneously, I was looking for a way to ensure you cannot have concurrent timer events - seems to occur during app restart (DLLs change in /bin
, app restart via portal).
Configured function.json
to ignore trigger firing @ restarts via "runOnStartup": false
, but we still see concurrent executions if a function was running before the cycle. Seems like the locking doesn't account well for function updates (restart events) - it fires the trigger even though an existing process is already running. To verify this - use kudu process explorer and you'll see multiple processes for the same function.
For now - I just use kudu process explorer to kill any existing processes before making any app updates or restarting the function host - would be great if the portal allowed you to kill the process for a running azure function.
@alohaninja I am aware of the troubles with the restart. I usually stop the app before updating because of it, however all my functions are designed to be interrupted at any time.
If you look into your storage account you will see a container called azure-webjob-hosts. There will be several folders here {hostname}-{random-number} which contain a host.Functions.{function-name}.listener file for each timer-trigger function. This file is being used to lock with a blob lease.
Every time your app is (re)started a new folder is created ({hostname}-{random-number}). Since the new folder is empty there is no blob and no lease to check for, hence the parallel execution.
This should perhaps be a separate issue though.
I could really do with this feature to. The issue I have is that I need to call an external api based to get more data any time a message gets added to a queue. I tend to get around 300+ messages over a few minutes every 8 hours. The issue I'm having is azure spins up 16 servers to handle the spike in messages (which is cool...) however this is utterly destroying the server I'm calling.
I've set batch size and singleton in the host.json but that appears to have no impact (setting batch size just results in more servers being started).
I'm in desperate need of this as well. I have a bunch of webjobs I'd like to move to Azure Functions, but I can't because they need to run as singletons. Some are queue based and need to be run in order. Others call external apis that are very sensitive about how rapidly I call them.
To work around this I made a buffer queue and use a scheduled function to see how many items are in the processing queue and move a few items over depending on the count.
@BowserKingKoopa @rossdargan I haven't had time to experiment with it yet but in the configuration settings for host.json there's an option for WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT
. Sounds like it's still being worked on but using this in conjunction with batch size might help you achieve singleton semantics for the meantime.
Any updates on this please? Has anyone found a way to make enforce Functions run as a single instance max.
We also have a need for this. Both singleton and scale out limitation at function level.
I guess, if you can't wait for it to be implemented in SDK, you can use it already in Durable Azure Functions (https://docs.microsoft.com/en-us/azure/azure-functions/durable-functions-overview)
See section Stateful singletons
+1. Use case: Simple slack bot event handler, should only send message once.
@AntonChernysh I think you might be confused about Singleton behavior... There is nothing today preventing you from building a slack bot that only responds to messages only once
@WonderPanda looks like my function is scaling and running multiple times, therefore getting reply as many times as functions started. I have the same function (python 3.6) running on AWS lambda with no problem. I'd appreciate If you could advice something to make function run only once.
@AntonChernysh What triggers your function?
Any idea when singleton can be made available please? I'm implementing CQRS pattern with functions. My event publisher needs to be singleton so it can process the events in the right order/sequence. Thanks
@WonderPanda post message to function's HTTPs endpoint. Can we continue in skype? anton.chernysh
We would love this ability too.
The Consumption plan for Functions is incredibly enticing, but since we need to consume our queue messages one at a time, we're limited to web jobs only for now.
+1
I too have the need to process queue items one at a time in order, so a singleton is exactly what is needed.
Apparently this functionality exists, it just hasn't been documented for anything other that .net
https://github.com/Azure/azure-webjobs-sdk/wiki/Singleton