-
Notifications
You must be signed in to change notification settings - Fork 448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Singleton support for Functions to ensure only one function running at a time #912
Comments
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 |
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 |
@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:
@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 Configured 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 |
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. |
@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. |
@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 |
I have 1 function app (on the consumption plan) with 3 queue-triggered functions. Is this possible? I see a lot of different options here like I am using JavaScript but I am willing to switch to C# if it is easier to support this behavior. |
Dropping by in 2020 to see if this has been worked on yet... |
Still no news about this subject? |
#912 (comment) -- goes in-depth, not sure what you're looking for |
WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT was what I used to limit parallelism. |
Would like to add to this discussion, I saw this document today: Which seems to suggest that, we can use Azure Function with Service Bus Session trigger to achieve sequential processing of message. I have setup the following:
And a basic Function that will take a message out, wait 10 seconds, and end. function.json
index.js
From my testing result, messages with the same Session ID are processed one by one sequentially! Any idea if there are any drawback to my design that I do not aware, cause this seems like a very viable method to process sequential execution. Cheers! |
Yes I believe this is a viable approach. Messages sharing a session ID are processed in order, sequentially. One thing I'll note - I am not sure whether this interacts correctly with the FUNCTIONS_WORKER_PROCESS_COUNT setting. So to be safe, I would make sure that setting is absent (or set to 1, the default). |
Guys... `
` The instanceId is a constant in this case and this snippet is in a QueueTrigger Function. The problem is The QueueTrigger (Despite batch size being set to 1) scales up and starts consuming multiple messages simultaneously. This is NUTS! I added the |
@rohitashwachaks Does limiting the scale out not work for you, you can do it in the Azure Portal to prevent the function app scaling to more than 1 instance. https://docs.microsoft.com/en-us/azure/azure-functions/functions-scale#limit-scale-out |
@stap123 I have several other functions in the same Functions App. Setting the |
@rohitashwachaks Yeah we wanted the same thing. We just created a second function app and put the functions that were limited to 1 instance in that app and the other functions with default scaling in another app. |
@rohitashwachaks accordiing the docs: https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-singletons?tabs=csharp that should not be happening? Specifically the note:
|
checking in on a long open issue/discussion... was there a solution for this? |
is there any update for this? |
is there any solution for the singleton issue @rohitashwachaks? |
Hi everyone. I remember Microsoft fixed this race condition in their latest package version. Bit of a bummer. but I don't remember much else |
Hi @paulbatum, @fabiocav, @jeffhollan, @mathewc, @lindydonna and anyone else at MS that has engaged in this discussion throughout the year. I am sorry to include you all but this discussion is over 5 years in the making. Hopefully one of you are the right person to respond? It is such a pity that it is not possible to handle this easily in Azure functions (especially on consumption plan). Is there any chance that this will ever get implemented properly? What I feel is neededThere is A LOT of comments in this thread and it has kind of gone in different directions and spread of focus. Therefore I will repeat my need to clarify what I think will be a GREAT improvement (also the need expressed by a lot of other users in this issue):
There are options to control some of these things in host.json, but that will affect all functions in the app, so is too blunt of a tool. Also, the suggestion to have separate function apps to control execution has been mentioned, but that becomes very hard if you have more functions, with different config needs (code reuse/duplication, increased deployment aspect of creating many func apps etc.). Therefore not a good alternative in my mind. An example of how this could be handled on a function level could be in function.json Example for Function_A case
Example for Function_B case
Example for Function_C case
Example for Function_D case
These are just conceptual ideas but you get the idea. Thanks! |
@jaltin I hope this get picked up some day indeed. I've been bugging support for over a month now to achieve your Function_C case for .NET (on event grid binding). Every other language has FUNCTIONS_WORKER_PROCESS_COUNT to work with. |
Hi all wonderful people at Microsoft and other contributors that works on this repository (@paulbatum, @fabiocav, @mathewc, @NickCraver, @kaibocai, @heppersonmicrosoft, @pragnagopa, @siddharth-ms, @liliankasem, @alrod, @balag0 among others)! Im posting on this issue one more time hoping that someone of you all can have a look at my previous comment #912 (comment) and give a response on if you are considering this (it was after all created by one of your colleagues @mathewc). This is becoming more and more of a PITA for us to manage in scenarios where we have functions needing strict singleton controls, and at the moment it forces us to create separate function projects all over the place. Many of the posters here would loooooove to see something done to make our life's easier, so really hoping you can consider looking into it and try to address it in line with my suggested ideas. Thanks! |
It will be great if something like this will be added, I don't think is normal to do workarounds for a functionality that should be there. |
I too would love to have this kind of functionality to ensure Timer functions in particular only ever have a single instance running at a time... |
i find it very problematic that the docs https://learn.microsoft.com/en-us/azure/azure-functions/functions-host-json#singleton link to this issue to explain singleton behaviour...and this issue is a 100 comments none which do a great job of explaining any of this very well. the best i found regarding singleton is https://learn.microsoft.com/en-us/azure/app-service/webjobs-sdk-how-to#singleton-attribute but this is NOT in the context of functions just the underlying webjobs...which i know are related. the most useful comment in this thread is #912 (comment) which is burried in github UX. the relevant info needs to make it to the docs as it's own page mostly likely |
We have several queued functions, and most of them should be running in parallel as much as possible. There is one function in particular that can't, though. It communicates with an outside service that handles concurrency... poorly. I need just that one function to be a singleton, and I thought that the Singleton attribute was going to save me. Then I read here that it doesn't work on functions. But this comment says they DO work, albeit with billing implications. That's not what I'm seeing in my testing, though. I queued up multiple messages to my problem function and my logs show four of them starting before the first one finishes. It's a queue-triggered function, and I've tried the Singleton attribute with and without specifying a scope. It seems to just rip through the queue no matter what. I can't just change the host.json to a batch size of one because that will kill the performance of all the other functions that are perfectly happy running in parallel. What can I do? |
Fyi the way i’ve achieved singleton success is leveraging durable entities. My triggers queue the work on SignalEntityAsync. Entities will process one signal at a time. if you need http triggered singleton with a response u have to get tricky and loop GetEntityState() the entity for work completion (and when queueing probably throw in an id) and if its gonna take a while (10mins) respond with a 301 to a diff http trigger that keeps looking for the work to be done or loops again. its def no [Singleton] but its been very successful. |
This doesn't seem to work for "ServiceBus" triggers, it's not auto extending the service bus lock. While it is running in singleton mode, it's pointless if the lock isn't being extended on the ones waiting. using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
namespace TestFunctions;
public static class ServiceBusQueueTrigger1
{
[FunctionName("ServiceBusQueueTrigger1")]
[Singleton(Mode = SingletonMode.Function)]
public static async Task RunAsync([ServiceBusTrigger("testqueue", Connection = "ServiceBusConnection")] string myQueueItem, ILogger log)
{
log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
await Task.Delay(30000);
log.LogInformation($"C# waited 30sec processed message: {myQueueItem}");
}
}
|
Wow. Dear MS devs (@paulbatum, @fabiocav, @mathewc, @NickCraver, @kaibocai, @heppersonmicrosoft, @pragnagopa, @siddharth-ms, @liliankasem, @alrod, @balag0 among others) - have another look at this - also for non-.Net FnApps? |
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#)
The text was updated successfully, but these errors were encountered: