Unable to disable lock on Session (maybe) - asp.net

After a previous post about an issue with Session State being locked on every request (normal behavior for Asp.Net), tried fully disabling Session State (). This, in fact, disables the Session object and throws exceptions if try to use it. However, as stated in the named post, all requests are still serviced in a serialized fashion. This is, a second "simultaneous" request doesn't get served till previous gets finished served. Related documentation states that disabling Session State avoids the lock in the session but, in my case, my requests are still serviced serially.
This is not MVC.
This is my previous post Custom handler processes multiple requests serially and not simultaneouslly
Any help would be appreciated.

Turns out this always happens inside the developer environment (cassini). When dissabling session state there is no possible access to the Session object but it seems to exists a lock request somewhere.
Debugging in IIS this doesn't happen.
Hope this help.

Related

ASP Session State Overview

I work on a classic ASP web site that uses ASP session state to hold sate information. We use the sql database implementation of ASP session state.
We are having problems where sessions are being left locked and then subsequent requests to that session pile up into big queues that are affecting our performance. I don't expect you to be able to fix this for me but maybe someone could give me an overview of session state, as I don't think that i fully understand it.
None of our pages are marked as read only so all of our requests to the session database are exclusive (TempGetStateItemExclusive3); which in turn places a lock on the session.
I understand that if a modification to session is made that we update the session in the database (TempUpdateStateItemShort) and part of that process removes the lock.
I also understand that if we abandon a session that the lock is removed by (TempRemoveStateItem).
I also understand that that a sql agent job occurs periodically to delete expired sessions.
What I don't understand is how we abandon a session or how we release locks on sessions that we have locked through a Get but dont update?
I have read the following to get this far in my understanding http://msdn.microsoft.com/en-gb/library/aa478952.aspx and http://msdn.microsoft.com/en-us/library/aa479041.aspx
As always any help will be gratefully received and appreciated.
I have spent some more time looking into this and i think that i have figured it out.
Abandoning a session is an explicit action, Session.Abandon()
Releasing a lock is an implicit action
On the page_load event a call to TempGetStateExclusive3 is made to get the session object. Exiting the page_load implicitly calls TempReleasStateItemExclusive. As a developer you are only in control of abandoning a session, the locking is handled for you by the framework.
This does not fix my issue with sessions being left locked. But at least now I know how sql server session state should work.
Thanks

Error during GENERAL_REQUEST_ENTITY for POST request causes ASP .NET session state to never get unlocked

(Cross posting from Server Fault where I wasn't getting any traction):
I have been trying to chase down the root cause of a condition where ASP .NET session state remains locked after a web request has been terminated due to an unexpected error. We use the SQL Server session state provider for session because we have several servers in a web farm. This issue first presented itself in the form of many requests getting stuck on the 'AcquireRequestState' event of their lifecycle for no apparent reason. I was able to finding corresponding entries for these requests in the session state database in SQL server that were all locked (column Locked = 1). I was also able to correlate these requests to entries in the IIS log with HTTP status codes of 500 (with a sub status of 0). These findings lead me to believe that, in some cases, a request was erroring out but was NOT releasing its lock on session state like it should.
I enabled Failed Request Tracing in IIS for the website in question for status code 500 with all available providers selected each with the 'Verbose' setting for verbosity. I've since gathered several failed traces that have caused permanently locked ASP .NET sessions. They all share the same characteristics:
They are all 'POST' requests where the browser is posting data to be processed/saved.
They all have events indicating that the 'Session' module was invoked during the REQUEST_ACQUIRE_STATE event. At this point the request would have marked the row in the session state database as being "locked". This is normal and expected.
They all have GENERAL_READ_ENTITY_START, GENERAL_READ_ENTITY_END, and GENERAL_REQUEST_ENTITY entries that appear to be reading in the data that was posted to the server as part of the request. This appears to be a buffered operation as these events get repeated over and over with each one reading in some subset of the posted data.
At some point during the 'read entity' related events an error occurs. Some have the error code "Incorrect function. (0x80070001)" and others have "The I/O operation has been aborted because of either a thread exit or an application request. (0x800703e3)".
Once the error has been encountered, they all jump directly to the END_REQUEST events.
The issue here is that, under normal circumstances, there should be a RELEASE_REQUEST_STATE event that will allow the Session module to release the lock it has on the session. This event is being skipped in this scenario. Just to be sure, I enabled failed request tracing for the '200' status code as well and generated several traces of successful requests that do have the RELEASE_REQUEST_STATE event being handled by the Session module.
A co-worker pointed out that you can also cause a request to skip directly to the 'END_REQUEST' event by calling HttpContext.Current.ApplicationInstance.CompleteRequest(). I tested this out and saw that using this method during a post request creates a trace very similar to the ones I've been capturing when this issue has been happening, but session does still get cleaned up properly. This lead to me to running SQL Profiler on the SQL Server database where the session is stored to trace all calls to stored procedures. When we skip directly to END_REQUEST due to calling CompleteRequest(), a call is made to update the session state (and release the lock) as expected. When we skip to END_REQUEST as a result of an error during GENERAL_REQUEST_ENTITY, the call to update or release the lock on session state is never made.
My theory at this point is that some kind of network issue is causing the 'Incorrect function' and 'I/O operation has been aborted because of either a thread exit or an application request' errors, but I don't understand why this seems to be causing the request handling to skip over the releasing the lock on session state. If the request went through REQUEST_ACQUIRE_STATE it seems like it should also release the lock at some point toward the end of the request as well. I'm loathe to say that this is a bug in IIS or ASP .NET, but it certainly appears that way to me at this point.
Are there any known conditions under which errors will lead to a session state lock not being released?
As it turns out, this was related to this question: ManagedPipelineHandler for an AJAX POST crashes if an IE9 user navigates away from a page while that call was in progress
The workaround specified in the accepted answer on that question does work, but Microsoft has also since released a hotfix (not yet publicly available as of this writing) that patches the session handling logic to avoid the issue all together.

ASP.NET application to serve multiple requests from a single process

I am currently debugging some issue about this.
We have a ASP.NET web application and I am debugging on Cassini. When I tried to use IE and send out the request to the server, some time (e.g. in about 20minutes) is needed to process and then send out the response.
In case of multi-tab IE, I tried to send out the requests in different tab at about the same time to the same server but the response is handled only after the one of the response is sent out.
If a new instance of IE is started and the requests are sent out in these different instances, the server can process and send out the response almost simultaneously. After doing some research I found that IIS express may solve my problem, but I cannot. Anyone has experienced similar problem or have I missed out some really important things to check with first?
Thank you for your help.
This is primarily due to ASP.net's session state variable and the fact that only one request at a time may have R/W access to a particular session (as determined by the SessionID cookie).
Any additional requests requiring any form of session access (since Read/Write is the default) will be blocked until the previous request has been completed.
Based on the following links:
http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/
https://msdn.microsoft.com/en-us/library/ms178581.aspx?f=255&MSPPError=-2147217396
I think that you miss the point that the session is lock all request leaving only one per time to run.
Read about that and why:
Replacing ASP.Net's session entirely
Also : Web app blocked while processing another web app on sharing same session
The reason is that Sessions in ASP.NET are not thread safe. Therefore ASP.NET serializes access to requests from the same session.
If you have a multi-tab IE then your tabs share one session. The first request is executed right off and the other ones are queued. If you have different instances then each of them creates a new session and therefore the request are executed in parallel.

Please wait page in Spring MVC + Apache Tiles

I'm using Spring MVC 3 + Tiles for a webapp. I have a slow operation, and I'd like a please wait page.
There are two main approaches to please wait pages, that I know of:
Long-lived requests: render and flush the "please wait" bit of the page, but don't complete the request until the action has finished, at which point you can stream out the rest of the response with some javascript to redirect away or update the page.
Return immediately, and start processing on a background thread. The client polls the server (in javascript, or via page refreshes), and redirects away when the background thread finishes.
(1) is nice as it keeps the action all single-threaded, but doesn't seem possible with Tiles, as each JSP must complete rendering in full before the page is assembled and returned to the client.
So I've started implementing (2). In my implementation, the first request starts the operation on a background thread, using Spring's #Async annotation, which returns a Future<Result>. It then returns a "please wait" page to the user, which refreshes every few seconds.
When the please wait page is refreshed, the controller needs to check on the progress of the background thread. What is the best way of doing this?
If I put the Future object in the Session directly, then the poll request threads can pull it out and check on the thread's progress. However, doesn't this mean my Sessions are not serializable, so my app can't be deployed with more than one web server (without requiring sticky sessions)?
I could put some kind of status flag in the Session, and have the background thread update the Session when it is finished. I'm very concerned that passing an HttpSession object to a non-request thread will result in hard to debug errors. Is this allowed? Can anyone cite any documentation either way? It works fine when the sessions are in-memory, of course, but what if the sessions are stored in a database? What if I have more than one web server?
I could put some kind of status flag in my database, keyed on the session id, or some other aspect of the slow operation. It seems weird to have session data in my domain database, and not in the session, but at least I know the database is thread-safe.
Is there another option I have missed?
The Spring MVC part of your question is rather easy, since the problem has nothing to do with Spring MVC. See a possible solution in this answer: https://stackoverflow.com/a/4427922/734687
As you can see in the code, the author is using a tokenService to store the future. The implementation is not included and here the problems begin, as you are already aware of, when you want failover.
It is not possible to serialize the future and let it jump to a second server instance. The thread is executed within a certain instance and therefore has to stay there. So session storage is no option.
As in the example link you could use a token service. This is normally just a HashMap where you can store your object and access it later again via the token (the String identifier). But again, this works only within the same web application, when the tokenService is a singleton.
The solution is not to save the future, but instead the state of the work (in work, finished, failed with result). Even when the querying session and the executing threads are on different machines, the state should be accessible and serialize able. But how would you do that? This could be implemented by storing it in a database or on the file system (the example above you could check if the zip file is available) or in a key/value store or in a cache or in a common object store (Terracota), ...
In fact, every batch framework (Spring Batch for example) works this way. It stores the current state of the jobs in the database. You are concerned that you mix domain data with operation data. But most applications do. On large applications there is the possibility to use two database instances, operational data and domain data.
So I recommend that you save the state and the result of the work in a database.
Hope that helps.

Access Session on End?

I am trying to "log" forcefully when a user has been inactive and or the session has ended (either by inactivity or more importantly, when the browser has closed).
I dont want to use any silly AJAX solution to perform a post every few minutes for "im alive" or call when the browser is closed.
I was under the impression that if you store an object in Session, and you reach the Session_End event, then you will not be able to gain access to anything stored in Session as its ended.
But from some testing I have done, it appears that this is probably the last chance you can obtain access to the object.
Could this be true? is it reliable?
using ASP.NET 4.0 here.
Typically there are two things done.
The first is that a javascript timer is added to the client, not as a heartbeat, but rather as a reminder. If they are close to the session ending, then it simply says "session is about to end. Are you still there?" If so, then it does the "silly" post to ensure the server keeps the session going. This is purely to be nice to your users.
The second (and point of your question) is that you put something in session_end in order to clean up the session. Reliable? well.. most of the time.
Session_End won't run if the app pool is recycled. However, assuming the app pool is ok then yes it will execute when the session expires. The app pool can be recycled for a LOT of reasons ranging from the app crashing to exceeded memory usage to simply because it's been a while since the last reset. This is configurable in IIS.
Would I trust session_end? No. Not 100%. Of course, I wouldn't put anything inside of a session object that would require me to trust it 100% anyway.
For logging the timeout You can use the Global events to log at timeout. See this link for order of events http://www.techrepublic.com/article/working-with-the-aspnet-globalasax-file/5771721

Resources