Saturday, January 12, 2013

The Session Story

Prologue

Programming in ASP.NET we use the Session object in order to keep user information on the server while the user is working with the application. That way you can easily access that information when the server is working and require that information. Usually we use the session on the main ASP.NET thread. What would happen if you use the session in another thread? Can you update the session while on another thread? So here is the story.

The Feature

We developed a very cool feature which enables users to upload their PDF files, and then view and manipulate them before completing an order for printing the composite document. When a user uploads a file we have to analyse it and turn its pages into images (in order to display them in the browser). This processing takes time. The user will have to wait, but we do not want the web server to wait, taking over application pool threads, but rather do this processing in separate threads.

The Problem

When the processing of a file completes we need to update the session object with the newly uploaded file and its properties, so we could handle the order on the server side. At first, we did this update on the same thread that did the processing. When we use In Proc session state mode it worked well, but when we use SQL Server session state mode (required for clustering), the session will not update.

Why?

We wondered why does it work that way. At first it felt very strange and we said it's probably some bug. But we also felt that it may be that we are misusing the session, so we did some more research and thinking, and this is what we came up with.
In Proc session state mode simply keeps the session in memory. When we update the session from one thread and then read it from the main thread, they both access the same place in memory, so it works.
SQL Server session state mode needs to serialize the session to the database in order to save it, and deserialize it in order to read it. Deserialization occurs when a request hits the server, and serialization occurs when the request ends and the response goes to the client.
When updating the session in another thread, it happens after the request ends, and it also occurs after the session was serialized and saved in the database, so this explains why it cannot work that way.
Doing some further reading, I found out that the session was designed to work only in the scope of a request, so also in the case of using only In Proc session state mode, updating the session from another thread after the request is over is an abuse and breaks the session design.

The Solution

We decided to simply change our design a bit, so the request to upload a file, which triggers its processing and should have saved it to the session, will not do the saving. Instead, as the client waits for processing to end by asking the server whether processing is over, when the server finds out processing is done, it saves the file information to the session, and returns the correct response to the client. That's easy to implement and easy to understand.

Epilogue

So far I was only telling stories on this blog. I hope to put some code into my next post, so keep on following!