Is ASP.NET Core Session implementation thread safe? - multithreading

I know that there is an analogous question but that is about ASP.NET and not about ASP.NET Core. The answers are 7-9 years old, and mixing there talking about ASP.NET and ASP.NET Core may not be a good idea.
What I mean thread safe in this case:
Is it safe to use the read write methods (like Set(...)) of the Session (accessed via HttpContext, which accessed via an injected IHttpContextAccessor) in multiple requests belonging to the same session?
The obvious answer would be yes, because if it would not be safe, then all developers should make their session accessing code thread safe...
I took a look of the DistributedSession source code which seems to be the default (my session in the debugger which accessed as described above is an instance of DistributedSession) and no traces of any serialization or other techniques, like locks... even the private _store member is a pure Dictionary...
How could be this thread safe for concurrent modification usage? What am I missing?

DistributedSession is created by DistributedSessionStore which is registered as a transient dependency. That means that the DistributedSessionStore itself is implicitly safe because it isn’t actually shared between requests.
The session uses a dictionary as the underlying data source which is also local to the DistributedSession object. When the session is initialized, the session initializes the _store dictionary lazily when the session is being accessed, by deserializing the stored data from the cache. That looks like this:
var data = _cache.Get(_sessionKey);
if (data != null)
{
Deserialize(new MemoryStream(data));
}
So the access to _cache here is a single operation. The same applies when writing to the cache.
As for IDistributedCache implementations, you can usually expect them to be thread-safe to allow parallel access. The MemoryCache for example uses a concurrent collection as the backing store.
What all this means for concurrent requests is basically that you should not expect one request to directly impact the session of the other request. Sessions are usually only deserialized once so updates that happen during the request (by other requests) will not appear.

Related

Is there a recommended approach for object creation in Node.js?

I know that in PHP objects are created for each request and destroyed when the processing is finished.
And in Java, depending on configuration, objects can remain in memory and be either associated with a single user (through server sessions) or shared between multiple users.
Is there a general rule for this in Node.js?
I see many projects instantiating all app objects in the entry script, in which case they will be shared between requests.
Others will keep object creation inside functions, so AFAIK objects are destroyed after processing each request.
What are the downsides of each approach? Obviously, things like memory usage and information sharing should be considered, but are there any other things specific to Node.js that we should pay attention to?
Javascript has no such thing as objects that are tied to a given request. The language is garbage collected and all objects are garbage collected when there are no more references to them and no code can reach them. This has absolutely nothing to do with request handlers.
so AFAIK objects are destroyed after processing each request.
No. The lifetime of objects in Javascript has absolutely nothing to do with requests.
Instead, think of function scopes. If you create an object in a request handler and use it in that request handler and don't store it somewhere that creates a long lasting reference to the object, then just like ANY other function in Javascript, when that request handler function finishes and returns and has no more asynchronous operations still in-flight, then any objects created within that function that are not stored in some other scope will be cleaned up by the garbage collector.
It is the exact same rules for a request handler as it is for any other function call in the language.
So, please forget anything you know about PHP as its request-specific architecture will only mess you up in Javascript/node.js. There is no such thing in node.js.
Instead, think of a node.js server as one, long running process with a garbage collector. All objects that are created will be garbage collected when they are no longer reachable by live code (e.g. there are no live references to them that any code can get to). This is the same whether the object is created at startup of the server, in a request handler on the server, in a recurring timer on the server or any other event on the server. The language has one garbage collector that works the same everywhere and has no special behavior for server requests.
The usual way to do things in a node.js server is to create objects that are local variables in the request handler function (or in any functions that it calls) or maybe even occasionally assigned as properties of the request or response objects (middleware will often do this). Since everything is scoped to a function call in the request chain when that function call is done, the things you created as local variables in those functions will become eligible for garbage collection.
In general, you do not use many higher scoped variables outside the request handler except for purposeful long term storage (session state, database connections, or other server-wide state).
Is there a general rule for this in Node.js?
Not really in the sense you were asking since Javascript is really just about the scope that a variable is declared in and then garbage collection from there, but I will offer some guidelines down below.
If data is stored in a scope higher than the request handler (module scope or global scope), then it probably lasts for a long time because there is a lasting reference that future request handlers can access so it will not be garbage collected.
If objects are created and used within a request handler and not attached to any higher scope, then they will be garbage collected by the language automatically when the function is done executing.
Session frameworks typically create a specific mechanism for storing server-side state that persists on the server on a per-user basis. A popular node.js session manager, express-session does exactly this. There, you follow the rules for the session framework for how to store or remove data from each user's session. This isn't really a language feature as it is specific library built in the language. Even the session manage relies on the garbage collector. Data persists in the session manager when desired because there are lasting references to the data to make it available to future requests.
node.js has no such thing as "per-user" or "per-request" data built into the language or the environment. A session manager builds "per-user" data artificially by making persistent data that can be requested or accessed on a per-user basis.
Some general rules for node.js:
Define in your head and your design which data is local to a specific request handler, which data is meant for long term store, which data is meant for user-specific sessions. You should be very clear about that.
Don't ever put request-specific variables into any higher scope that any other request handler can access unless these are purposeful shared variables that are meant to be accessed by multiple requests. Accidentally sharing variables between requests creates concurrency issues and race conditions and very hard-to-track-down server bugs as one request may write to that variable in doing it's work and then another request may come along and also write to it, trouncing what the first request was working on. Keep these kind of request-specific variables local to the request handler (local to the function for the request handler) so that can never happen.
If you are storing data for long term use (beyond the lifetime of a specific request) which would generally mean storing it in a module scoped variable or in a global scoped variable (should generally not use global scoped variables), then be very, very careful about how the data is stored and accessed to avoid race conditions or inconsistent state that might mess up some other request handler reading/writing to that data. node.js makes this simpler because it runs your Javascript as single threaded, but once your request handler makes some sort of asynchronous function call (like a database call), then other request handlers get to run so you have to be careful about modifications to shared state across asynchronous boundaries.
I see many projects instantiating all app objects in the entry script, in which case they will be shared between requests.
In the example of an web server using the Express framework, there is one app object that all requests have access to. The only request-specific variables are the request and response objects that are created by the web server framework and passed into your request handler. Those will be unique to each new request. All other server state is accessible by all requests.
What are the downsides of each approach?
If you're asking for a comparison of the Apache/PHP web server model to the node.js/Express web server model, that's a really giant question. They are very different architectures and the topic has been widely discussed and debated before. I'd suggest you do some searching on that topic, read what has been previously written and then ask a more specific question about things you don't quite understand or need some clarification on.

web app, jsp, and multithreaded

I'm currently building a new web app, in Java EE with Apache Tomcat as a webserver.
I'm using jsps and servlets in my work.
my question is:
I have a very standard business logic. None of it is synchronized, will only a single thread of my web app logic will run at any given time?
Since making all functions "synchronized" will cause a huge overhead, is there any alternative for it?
If i have a static method in my project. that makes a very simple thing, such as:
for (int i=0;i<10000;i++ ) {
counter++;
}
If the method is not thread safe, what is the behavior of such method in a multi user app? Is it unexpected behavior?!
and again in a simple manner:
if i mean to build a multi user web app, should i "synchronize" everything in my project? if not all , than what should i sync?
will only a single thread of my web app logic will run at any given time?
No, the servlet container will create only one instance of each servlet and call that servlet's doService() method from multiple threads. In Tomcat by default you can expect up to 200 threads calling your servlet at the same time.
If the servlet was single-thread, your application would be slow like hell, see SingleThreadModel - deprecated for a reason.
making all function "synchronized" will make a huge overhead, is there any alternative for it?
There is - your code should be thread safe or better - stateless. Note that if your servlet does not have any state (like mutable fields - unusual), it can be safely accessed by multiple threads. The same applies to virtually all objects.
In your sample code with a for loop - this code is thread safe if counter is a local variable. It is unsafe if it is a field. Each thread has a local copy of the local variables while all threads accessing the same object access the same fields concurrently (and need synchronization).
what should i sync?
Mutable, global, shared state. E.g. In your sample code if counter is a field and is modified from multiple threads, incrementing it must be synchronized (consider AtomicInteger).

ColdFusion singleton object pool

In our ColdFusion application we have stateless model objects.
All the data I want I can get with one method call (it calls other internally without saving the state).
Methods usually ask the database for the data. All methods are read only, so I don't have to worry about thread safety (please correct me if I'm wrong).
So there is no need to instantiate objects at all. I could call them statically, but ColdFusion doesn't have static methods - calling the method would mean instantiating the object first.
To improve performance I have created singletons for every Model object.
So far it works great - each object is created once and then accessed as needed.
Now my worry is that all requests for data would go through only 1 model object.
Should I? I mean if on my object I have a method getOfferData() and it's time-consuming.
What if a couple of clients want to access it?
Will second one wait for the first request to finish or is it executed in a separate thread?
It's the same object after all.
Should I implement some kind of object pool for this?
The singleton pattern you are using won't cause the problem you are describing. If getOfferData() is still running when another call to that function gets called on a different request then this will not cause it to queue unless you do one of the following:-
Use cflock to grant an exclusive lock
Get queueing connecting to your database because of locking / transactions
You have too many things running and you use all the available concurrent threads available to ColdFusion
So the way you are going about it is fine.
Hope that helps.

Spring + Hibernate session management across multiple threads

I am building a system, where each request from a client side spawns multiple threads on server side. Each thread then is using one or more DAOs (some DAOs can be used by more than one thread at the time). All DAOs are injected (#Autowired) to my thread classes by Spring. Each DAO receives SessionFactory injected as well.
What would be proper way of managing Hibernate sessions across these multiple DAOs so I would not run into problems because of multithreaded environment (e.g. few DAOs from different threads are trying to use the same session at the same time)?
Would be enough that I specify hibernate.current_session_context_class=thread in Hibernate configuration and then everytime in DAO simply use SessionFactory.getCurrentSession() to do the work? Would it properly detect and create sessions per thread as needed?
Yes. It is enough.
When setting hibernate.current_session_context_class to thread , the session returned from SessionFactory.getCurrentSession() is from the ThreadLocal instance.
Every thread will have their own, independently ThreadLocal instance, so different threads will not access to the same hibernate session.
The behaviour of SessionFactory.getCurrentSession() is that: if it is called for the first time in the current thread, a new Session is opened and returned. If it is called again in the same thread, the same session will be returned.
As a result , you can get the same session to use in different DAO methods in the same transaction code by simply calling SessionFactory.getCurrentSession(). It prevents you from passing the Hibernate session through the DAO method 's input parameters in the case that you have to call many different DAO methods in the same transaction code.

NPAPI threading model: should access to global variables be protected by a lock?

From https://developer.mozilla.org/En/Gecko_Plugin_API_Reference:Scripting_plugins :
This API is not designed to be thread safe. The threading model for this API is such that all calls through this API are synchronous and calls from a plugin to methods in this API must come from the thread on which the plugin was initiated, and likewise all calls to methods in this API by the browser are guaranteed to come from the same thread. Future revisions to this API might provide a mechanism for proxying calls from one thread to another to aid in using this API from other threads.
If I want to access a global variable in my plugin (shared between all instances, even on different pages), do I need to lock it or does the browser use only one thread to communicate with the plugin for all instances?
The browser always uses exactly one thread to communicate with the plugin for all instances; you should do the same in return and never call any NPN_ functions from other than the main thread.
Keep in mind that if you're doing anything that may block the main thread at all you'll want to create your own threads and in that case you may need locking; however, just for the browser? no, you don't need them.

Resources