Does azure functions share context between the running instances? - c#

I'm working on one project based on the Azure Functions, and I have one static helper class with buffer (private static ConcurrentDictionary) which holds some list of items to be processed at the end of execution, the question does this buffer will be shared between the multiple running instances?

It depends.
Most commonly, multiple executions of functions will run on the same instance. meaning the same .NET process and application domain, so they will share your static dictionary.
If your Function App gets too many requests to handle on a single instance, a second instance will be created, and it won't share anything with the first instance. So, you will have 2 (and 3, 4, N if needed) dictionaries in this scenario.
Any of those instances can also disappear at any moment in time, so you can't reliably store anything in the dictionary between executions. You can do that with "best effort", e.g. to cache data.

Azure Functions don't necessarily run on the same machine each time they are invoked, which means shared memory will be volatile as a future invocation may occur on a completely new machine.
Ideally, design things to be stateless and use a technology more suited to queueing tasks for later, such as an Azure queue.
If you must keep some state, put it somewhere more permanent such as the %HOME% directory or in storage.

Related

Is it safe to use a C# static class as a means of sharing data from one azure function to another?

I have two functions under a Azure function plan. Also included in there is a static class with a public static string. Can I use this static string as a means of transferring data from one function to the other?
The main concern I have is regarding instances. If each trigger creates a new copy of the static class and its string content then I believe this shouldn't be a problem. So does each trigger of the first function that calls the static class create a new copy for itself of it or is it shared among different simultaneous function clients?
Should I look for an alternative approach like Redis cache or something similar?
Azure function is serverless. If you are running under a consumption plan multiple function instance will start executing and when instance is idle, it will release instances.
Maintaining state outside function is best approach.
I used Redis for same and seen lot of performance improvement in my application. If you have frequent read/write Redis is best option and you have to pay a dedicated amount for Redis instance.
If function request is not very frequent or budge is constant, you can use "Azure Storage Table" as well. you don't need to pay a dedicated amount.
Azure Functions offers an alternative for creating stateful functions called Durable Functions. Durable Functions is an extension to the Azure Functions runtime that enables the definition of stateful workflows in code.
For more information follow the below docs.
https://learn.microsoft.com/en-us/dotnet/standard/serverless-architecture/durable-azure-functions
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview
The best way to achieve what you are trying to do is to use queues with payloads.
Basically one functions puts the data you want to transfer in a queue. The other function has a Queuetrigger that once a message shows will run (being able to access the data)

How do you use variables across C# classes while resetting them every call?

I am creating a web API in ASP.Net with IIS. However, I have been storing class members statically so that they can be accessed across different classes. This is obviously bad practice and I am noticing that every time a request is being made for the API, the same values are being returned due to the members not being cleared. How would I clear the members every request while also being able to access them across classes?
You should almost never use static variables in a web application. Even if you want to share variables across requests, access to statics is not thread-safe in many cases, and that can result in corrupt memory, incorrect system behavior, and even total system failure (if you're unlucky).
If you have variables that need to be shared, use an application variable instead. If you need to have a common cache, use one of the established caching techniques.
As for your specific question
How would I clear the members every request while also being able to access them across classes?
I think there is a misunderstanding here. There is no absolutely no reason to re-use a variable if it is being reset every time. I am guessing you think there is a performance cost to allocating new variables with each request; this is false. It is actually less efficient to use shared variables as multiple threads will experience false sharing and have to wait for each other as each request completes. If you use a new set each time, each thread has its own sandbox to work in and can complete the request much more quickly.
Instead, store your variables locally or as member variables in an object that is discarded at the end of the request. If you need some common location across all modules within a request, you can use HttpContext.Item or one of its alternatives.

System.Runtime.Caching.MemoryCache is it shared across processes in the same server

I have multiple windows services running, which are on different processes, is the System.Runtime.Caching.MemoryCache common for these processes or is it separate instance for each process?
If not, is there a caching mechanism that shares the same instance of cache namespace on .net in a server.
I am not looking for distributed caching like redis. I want to share the in memory cache within ONE server but with multiple processes so its much faster, rather than going over network to another server and getting the data, deserializing it, etc.
The System.Runtime.Caching.MemoryCache only works within a single process. Your best solution is to use a distributed cache (like Redis, Memcache, ...) with a single server (the server you are running your apps on).
C# objects can't be directly passed across process spaces, so there is inevitably some sort of serialization that will happen.
MemoryCache does not allow you to share memory between processes as the memory used to cache objects is bound to the application pool. That's the nature of any in-memory cache implementation you'll find.
The only way to actually use a shared cache is to use a distributed cache.
However, there are ways to share memory in C# but that's not actual caching anymore.
You can use memory mapped files for example, as pointed out in an older answer here sharing memory between two applications

Should I lock a datatable in multithread paradigm?

In a project of windows services (C# .Net Platform), I need a suggestion.
In the project I have class named Cache, in which I keep some data that I need frequently. There is a thread that updates cache after each 30 minutes. Where as there are multiple threads which use cache data.
In the cache class, there are getter and setter functions which are used by user threads and cache updater thread respectively. No one uses data objects like tables directly, because they are private members.
From the above context, do you think I should use locking functionality in the cache class?
The effects of not using locks when writing to a shared memory location (like cache) really depend on the application. If the code was used in banking software the results could be catastrophic.
As a rule o thumb - when multiple threads access the same location, even if only one tread writes and all the other read, you should use locks (for write operation). What can happen is that one thread will start reading data, get swiped out by the updater thread; So it'll potentially end up using a mixture of old and new data. If that really as an impact depends on the application and how sensible it is.
Key Point: If you don't lock on the reads there's a chance your read won't see the changes. A lock will force your read code to get values from main memory rather than pulling data from a cache or register. To avoid actually locking you could use Thread.MemoryBarrier(), which will do the same job without overhead of actually locking anything.
Minor Points: Using lock would prevent a read from getting half old data and half new data. If you are reading more than one field, I recommend it. If you are really clever, you could keep all the data in an immutable object and return that object to anyone calling the getter and so avoid the need for a lock. (When new data comes in, you create a new immutable object, then replace the old with the new in one go. Use a lock for the actual write, or, if you're still feeling really clever, make the field referencing the object volatile.)
Also: when your getter is called, remember it's running on many other threads. There's a tendency to think that once something is running the Cache class's code it's all on the same thread, and it's not.

Is it OK to use static variables to cache information in ASP.net?

At the moment I am working on a project admin application in C# 3.5 on ASP.net. In order to reduce hits to the database, I'm caching a lot of information using static variables. For example, a list of users is kept in memory in a static class. The class reads in all the information from the database on startup, and will update the database whenever changes are made, but it never needs to read from the datebase.
The class pings other webservers (if they exist) with updated information at the same time as a write to the database. The pinging mechanism is a Windows service to which the cache object registers using a random available port. It is used for other things as well.
The amount of data isn't all that great. At the moment I'm using it just to cache the users (password hashes, permissions, name, email etc.) It just saves a pile of calls being made to the database.
I was wondering if there are any pitfalls to this method and/or if there are better ways to cache the data?
A pitfall: A static field is scoped per app domain, and increased load will make the server generate more app domains in the pool. This is not necessarily a problem if you only read from the statics, but you will get duplicate data in memory, and you will get a hit every time an app domain is created or recycled.
Better to use the Cache object - it's intended for things like this.
Edit: Turns out I was wrong about AppDomains (as pointed out in comments) - more instances of the Application will be generated under load, but they will all run in the same AppDomain. (But you should still use the Cache object!)
As long as you can expect that the cache will never grow to a size greater than the amount of available memory, it's fine. Also, be sure that there will only be one instance of this application per database, or the caches in the different instances of the app could "fall out of sync."
Where I work, we have a homegrown O/RM, and we do something similar to what you're doing with certain tables which are not expected to grow or change much. So, what you're doing is not unprecedented, and in fact in our system, is tried and true.
Another Pitfall you must consider is thread safety. All of your application requests are running in the same AppDomain but may come on different threads. Accessing a static variable must account for it being accessed from multiple threads. Probably a bit more overhead than you are looking for. Cache object is better for this purpose.
Hmmm... The "classic" method would be the application cache, but provided you never update the static variables, or understand the locking issues if you do, and you understand that they can disappear at anytime with an appdomain restart then I don't really see the harm in using a static.
I suggest you look into ways of having a distributed cache for your app. You can take a look at NCache or indeXus.Net
The reason I suggested that is because you rolled your own ad-hoc way of updating information that you're caching. Static variables/references are fine but they don't update/refresh (so you'll have to handle aging on your own) and you seem to have a distributed setup.

Categories

Resources