Skip to content

Document how to use static properties in C# to reuse objects between calls #158

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

Closed
christopheranderson opened this issue Jan 23, 2017 · 18 comments

Comments

@christopheranderson
Copy link
Contributor

christopheranderson commented Jan 23, 2017

You can use static properties to reuse C# objects between calls. This can lead to performance gains for complex objects or caching of objects from external stores. It is worth noting that you can't use this to store session information without a backing external store since a user might be on a different instance on each request.

Example: https://github.com/christopheranderson/azure-functions-app-insights-sample/blob/master/cs-http/run.csx#L9

@christopheranderson christopheranderson changed the title How to use static properties in C# to " How to use static properties in C# to reuse objects between calls Jan 23, 2017
@Richard004
Copy link

Great question and I would extend it with my concern.
The first thing I have tried when playing with functions was if a "static int counter" got persisted between two invocations. It did and kept being there for several minutes.
I liked that. Because as you correctly suggest, I can't wait to take advantage of that in caching of some "relatively expensive" shared readonly resources.
But, my question to the Azure Functions team is under what conditions can I expect this nice feature and should I be afraid of paying for all the minutes of "gigabyte seconds" when the process was obviously hanging in the memory, while not running?

@Richard004
Copy link

Oh I see. Sorry Christopher, your comment was not a question, but rather an answer. :-)

@lindydonna lindydonna changed the title How to use static properties in C# to reuse objects between calls Document how to use static properties in C# to reuse objects between calls Jan 27, 2017
@SyntaxC4
Copy link

SyntaxC4 commented Mar 6, 2017

@lindydonna - Can you expand on this topic as to why you should use this for resource sharing, but not state sharing between your functions?

@Richard004
Copy link

Sure. My function is a "stateless" service which takes request parameters from the user, uses some static resources and generates some output/report. The resources are "static" document templates + some form of expression source code which is stored on azure blob storage.

The static templates are typically not changed regularly unless an administrator releases/deploys new version once in few weeks. Therefore I call them "static" as they got reused per many requests.
The point is that it takes some time to download these resources to the function memory space and further to parse and "precompile" the expression source code and only then it can be "executed" against the request parameters.
And it gives big performance benefit if the static resource download and precompilation does not happen during each function request execution.

On the other hand, the "real state" is take care of in totally other part of larger system. So the Azure functions really serve as pure report/output generator.

Yes. Part of the scenario is actual download+"compile" our own language and then run our function via our interpreter.

If you take a broader look at what we are doing you must find us a seriously twisted.
"Why a hell would someone invent another language and tried to reproduce Azure functions functionality for Own functions?"
Hm.... and you may be right. But it just works for us.

Does that make sense? Or does that put me directly on the ban-list next to the other twisted freaks "They are not sane - They can not be helped. - For your own good, do not speak to them" :-)

But the funny thing is that what you guys are doing in Azure is every day closer and closer to what exactly we need. And that is just great.

@SimonLuckenuik
Copy link

Here is a good example of why static resource sharing can be useful: https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

Is there any kind of documentation available that explains the complete lifecycle of the code in C# specifically, like how are appdomains managed: is it one appdomain per execution per function? one appdomain per function reused between executions? one appdomain per function app shared by all function?

The only reference I found is the following: https://social.msdn.microsoft.com/Forums/azure/en-US/af640e9c-aea5-4967-9304-414f8d2461c6/unexplained-behavior-when-reference-library-changes-method-not-found?forum=AzureFunctions

But I am not sure it's reflecting your latest implementation.

@lindydonna
Copy link
Contributor

@SyntaxC4 I think Chris already explained it well in his comment. Because you can have multiple instances running, it's not a good idea to use static variables for session state between functions. For read-only data, it's very useful.

@Richard004
Copy link

I agree that the explanation from Chris is very good and matches my expectations. Honestly this is better that what I expected, but sill I would have a question regarding the charges.
What does count as the GigabyteSeconds of the "run" when it comes to the payments?
If there are static variables keeping its values between the function calls the process is obviously allocated in the "VM" memory between the calls. The process takes some GBs of private set of RAM.
Are we going to pay for these GBseconds between the runs?

@lindydonna
Copy link
Contributor

@Richard004 You won't be charged when a function is not executing. For example, the Functions runtime stays active for 5 minutes after the last function has finished executing, but customers don't pay this cost.

In other words, the unit is GB/sec, which means that if there is no active execution, the memory used doesn't matter.

@lindydonna lindydonna self-assigned this Apr 3, 2017
@lindydonna lindydonna added P2 and removed P1 labels May 16, 2017
@oribarilan
Copy link

Hey.
Can this property (caching properties between calls) also be used in Python?
I tried defining a class with a property but could not implement this..
Thanks

@paulbatum
Copy link
Member

@oribarilan No you cannot do this with python today, because currently we start a new python.exe process per execution. This approach has many other downsides too (such as poor performance). We are tracking work on a new language extensibility model here. If we are able to implement this model and move python to it then you'd see better performance and be able to use tricks like the one discussed above.

@nhwilly
Copy link

nhwilly commented Jun 14, 2017

Great information.

To make sure I'm not confused, this means I could take something thread safe, like an HTTP client, assign it to a static variable and if would be available for all my functions without having to create a new one each time.

Do I have that right?

@Nosmadas
Copy link

And as an extension to the previous question - will this behave the same in precompiled functions?

@fabiocav
Copy link
Member

@Nosmadas yes, the behavior for pre-compiled functions will be mostly identical. One thing to keep in mind is that, in that model, if you have multiple functions defined in your assembly, you have the ability to share static state across functions as well (not just invocations of the same function).

To accomplish the same with the dynamic (CSX) model, you'd need to load a shared assembly.

@lindydonna lindydonna removed their assignment Oct 6, 2017
@poida
Copy link

poida commented Dec 15, 2017

Does this work with javascript/node.js? Is it possible to share variables between invocations? I saw some mention of it in the comments of this page but nothing official.

@CoenraadS
Copy link

CoenraadS commented Sep 3, 2018

Apparently this thread is the first result for me if I google azure function dispose static object.

I was wondering if I could get an official best practice for dealing with static disposable objects.

One Stackoverflow comment mentioned doing something like:

AppDomain.CurrentDomain.ProcessExit += (s, e) => httpClient.Dispose();

Is this recommended?

Relevant stackexchange threads without clear answers:

https://stackoverflow.com/questions/48945526/do-we-have-to-take-care-of-garbage-collection-in-azure-function

https://stackoverflow.com/questions/52093109/redis-connection-best-practices-for-use-with-an-azure-consumption-function

@paulbatum
Copy link
Member

Your static objects such as long lived HttpClients will live for the lifetime of a given function instance. Once the process shuts down, typical garbage collection behavior will run. I do not recommend the code you outlined above. There is no need to explicitly call dispose on an object who's lifetime matches the lifetime of the process.

@CoenraadS
Copy link

CoenraadS commented Sep 9, 2018

My use-case was actually for interacting with a Redis server, of which I cannot get/set the timeout property. I understand by default Redis keeps connections open forever, so since I can't set a connection timeout (nor find out what its setting is, using an Azure Redis instance), I wanted to make sure I close the connection client side, else Redis will eventually throw a Max Clients error. I know Issues arn't meant for questions, but in such a use-case it would make sense to hook the process exit.

@ColbyTresness
Copy link

Closing this since reusing statics is a documented best practice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests