ASP.NET Single Worker Thread? (In Memory Session) - c#

I'm using in memory sessions in my ASP.NET MVC application which means that I can only have one single worker thread correct? Does this mean I have parallel processing in my application (think concurrent requests) or not? Does my application accept only 1 request at a time?
Edit: According to the IIS7 web site:
If the application uses in-process session variables,
the application will not function correctly, because the same user requests
are picked up by different worker processes that
do not share the same session details.
So this means in-memory session can only have 1 worker thread or not? See also here from the IIS7 forums.

Your application receives multiple requests at a time. Based on your edits and comments here you are looking for information on Web Gardens and sessions, as opposed to threads and session state.
Web Gardens use multiple processes and act like a load balancer when it comes to session state. Each process will have a separate in memory session store. IIS will send requests to any available process. Since the processes do not share session state then session usage will only really work if your session provider is shared between all the web garden processes.
Web Gardens only make sense if you use something like SQL Server for session state, and want to have affinity with a particular CPU/core. Since you can increase the number of threads this may be a more appropriate optimization for some users than using web gardens. However some applications may perform better with web gardens due to a particular work load or application characteristic. Use of web gardens in testing could also help work out some potential issues present under load balancing.
I believe it uses the .NET ThreadPool and has 20 threads by default. The each request coming into the server may be handled on a separate thread. The ASP.NET performance guidelines have some information on this topic.

In memory sessions means you should typically only have one front-end web server at a time, not a single worker thread :D
The reason being that any information stored in session on one machine is not available on the other. If you have two front-end web servers and your proxy or firewall does "load-balancing" whereby it will randomly assign requests to web servers, then you will have problems. That said, the problem is easily solved with so called "sticky sessions" where users are always sent to the same server.
-Oisin

Related

IIS web server and thread pool issues

Question is related ASP.NET 4.0 and IIS based azure cloud service:
need to know right number of IOCP threads to set for production web service where we make 10-20K/sec remote calls
Also need to know right number of Worker threads to set for production web service...specially to handle 10-20K/sec API calls...specially in bursts
Basically, I am facing issue that each of my cloud service VM should handle 10-20K requests/sec but it is not able to do so due to thread pool issue w.r.t. asp.net
my prod service does nothing but get data from redis and simply return
Assuming code is efficient and there is enough hardware i.e. there are no issues related to memory, cpu and n/w:
1. You should try to keep IOCP to minimal numbers 50-100
2. You should try to keep CPU threads to high to handle bursts of requests
I am not sure if it's a good idea to keep 2-5K active threads to cater to 10-20K requests/sec

Azure Load Balancer, IP Source, http session in MVC

Hi we have been working with the Azure Load Balancer and have the distribution mode set to IP Source. We are of course running multiple web machines.
We are using this with an MVC application. So far we haven't found any issues with maintaining session in Test.
My question is;
Is it normal practice to use IP Source to maintain sticky session's so that the client is always sent to the correct box running In Proc session?
Are there any issues with or pit falls with this setup.
I can't seem to find a definite answer anywhere.
The current best practice is to avoid server-side session state when possible; which ends up being about 95% of the time generally. To do this you would use Cookie-based Authentication in an ASP.NET MVC application. And most data stored within Session state can be cached or loaded on the fly with minimal impact to the system. After all, natively the web is stateless anyway.
IP Source based load balancing is fine; so is using server-side session state if necessary. However, the application really should be designed / built in a fashion that supports it being more stateless. That is that any Session data is just loaded appropriately if it doesn't exist. You really want to gracefully handle user requests without throwing an exception if at all possible so the user can keep getting their job done.
By keeping things more stateless you may get better application performance by using either Round-Robin or Performance based load balancing.

Maintaining Data across machines in the Cloud

I'm working on a Cloud-Hosted ZipFile creation service.
This is a Cross-Origin WebApi2 service used to provide ZipFiles from a file system that cannot host any server side code.
The basic operation goes like this:
User makes a POST request with a string[] of Urls that correlate to file locations
WebApi reads the array into memory, and creates a ticket number
WebApi returns the ticket number to the user
AJAX callback then redirects the user to a web address with the ticket number appended, which returns the zip file in the HttpResponseMessage
In order to handle the ticket system, my design approach was to set up a Global Dictionary that paired a randomly generated 10 digit number to a List<String> value, and the dictionary was paired to a Queue storing 10,000 entries at a time. ([Reference here][1])
This is partially due to the fact that WebApi does not support Cache
When I make my AJAX call locally, it works 100% of the time. When I make the call remotely, it works about 20% of the time.
When it fails, this is the error I get:
The given key was not present in the dictionary.
Meaning, the ticket number was not found in the Global Dictionary Object.
We (with the help of Stack) tracked down the issue to multiple servers in the Cloud.
In this case, there are three.
That doesn't mean there is a one-in-three chance of this working, what seems to be going on is this:
Calls made while the browser is on the cloud site work 100% of the time because the same machine handles the whole operation end-to-end
Calls made from other sites work far less often because there is no continuity between the machine who takes the AJAX call, and the machine who takes the subsequent REDIRECT to the website to download the file. It's simple luck of the draw if the same machine handles both.
Now, I'm sure we could create a database to handle requests, but that seems like a lot more work to maintain state among these machines.
Is there any non-database way for these machines to maintain the same Dictionary across all sessions that doesn't involve setting up a fourth machine just to handle queue?
Is the reason for the dictionary simply to have a queue of operations?
It seems you either need:
A third machine that hosts the queue (despite your objection). If you're using Azure, an obvious choice might be the distributed Azure Cache Service.
To forget about the dictionary and just have the server package and deliver the requested result, perhaps in an asynchronous operation.
If your ASP.NET web app uses session state, you will need to configure an external session state provider (either the Redis Cache Service or a SQL Server session state provider).
There's a step-by-step guide here.

Concurrent requests with a static value and webservices

I have a web server (ASP.NET - Mono 2.6.7) with a value static float x in it and two methods : getX() and setX(newX). I also have two clients one is a pc with c# console application and the other one is a mobile device with android (ksoap2). Both can access the web server.
What I do not know is : if my mobile device try to do a getX() while my pc is doing a setX(newX), will it result any trouble ?
Thanks.
It's not a good practice to have a state-full implementation for services. You can have different instances serving multiple requests. This is the case in ASP.NET web services. In WCF, using configuration, you can change instancing behavior. For example, you can have a single instance serving all requests (few of them can be concurrent) - in case, one has mutable state (as in your case), you have to synchronize the access to the state. Thread synchronization on shared state will create a bottleneck in serving the requests because at the most only one request thread can access the state. Further, you cannot scale horizontally (i.e. web farm scenario where requests will be served from multiple machines). If you choose to have multiple instances serving the request then you need to externalize the state e.g. put it into the database. In such case, you will incur in the penalty of accessing external data source (which can be much higher than thread synchronization) but you will have scalable design.
Roughly-speaking, a web service class/object should not be stateful in itself. You can store state, but it's usually externally, for example in a database.
This is because, depending on configuration, there's no guarantee that it will be the same instance of the class for every request for every client.

How does ADO.NET Connection Pooling work with .ASMX Web Services?

I've created an old-style .ASMX web service and would like to know how the built-in ADO.NET connection pooling works with it.
The web service is not using a singleton pattern, so it is instantiated anew with every request. My question is will connections be removed from the pool after each service request, or are they kept in the pool across requests? My service is called very frequently but I don't want to be doing setup and teardown of connections every time, if it can be avoided.
I have read that the pool is maintained for the AppDomain, but I'm not sure if each request generates a new AppDomain or not.
I am also curious if it would be beneficial to set Min Pool Size (to a small number other than 0) in this case.
Anyone know?
No each request does not generate a new app domain. All the requests for that web site/application are in the same application domain, and so share the connection pool. Once the asmx request is finished with the connection, it returns it to the pool and the next request in line grabs it (assuming there isn't another connection in the pool readily available).
One point of clarification. You can have two different web applications which point to the same code, and are in different app domains. The two applications don't share anything (think about launching the same application twice).
I am also curious if it would be
beneficial to set Min Pool Size (to a
small number other than 0) in this
case.
So it can be beneficial depending on the application. Creating connections takes time, so having some ready allows you to forgo that. If you have request that say uses one connection, that might be fine to make a person wait for (it all depends on fast you want the application to respond). This can really come into play when you need to say 3 or 4 different ones (you get the point) open for one request. So why would you need multiple connections? What about one for accessing data and a separate thread for logging to the database (logging to the database vs a file is a totally different conversation)? Now you need two. There are multiple scenarios where this can come into play. Depending on your database server holding an open connection can be pretty cheap, so setting it to a small number can be a huge bang for your buck. (For the record I've seen scenarios where connecting to a database took several seconds, like 3-5, so in that case holding an open connection for a user was beneficial.)
This is for Max Pool Size
No it's not beneficial, because all requests to that service use the same pool (assuming the connections are using the same connection string, and aren't hitting different servers. Those have separate connection pools). Having no available connections, is a really fast and surefire way of crushing the performance of your service.

Categories