Skip to content

Cory Foy

Organizational agility through intersecting business and technology

Menu
  • FASTER Fridays
  • Mapping Mondays
  • Player Embed
  • Search Videos
  • User Dashboard
  • User Videos
  • Video Category
  • Video Form
  • Video Tag
Menu

“Your Request is Processing”

Posted on February 4, 2005 by Cory Foy

The current project I am working on had a problem. The mobile users who were accessing the app were getting server 500 errors. But not from us, from the carrier’s proxy server. It seems our requests were taking too long, and the carrier’s proxy was just giving up.

The only way to remedy this was to keep the whole session alive by doing the Expedia type refresh that sends a page to the user saying “Your request is processing”, waits 5 seconds, and makes a request to the server. The server checks to see if the request is finished, if not, it sends out another “Processing” page, and if it is, it shows the results. Simple, right?

For a desktop application, it would be. Just kick the request off in another thread, register a callback to know when the thread is done, and continue on your merry way. But how do you do it with a web form, in a resuable way?

I first kicked around using a session variable to track the request, and a callback that would set this session variable:



protected void Page_Load(object sender, EventArgs e)

{

if(!Page.IsPostBack)

{

if(Request.QueryString["load"] != null)

{

if(Session["requestObject"] == null)

{

RequestObject obj = (ResultObject)Session["requestObject"];

DisplayResult(obj);

}

else

{

WriteLoadingCard();

}

}

}

}

private void cmdSubmit_Click(object sender, EventArgs e)

{

RequestObject req = new RequestObject(ID.Text, Name.Text);

RequestHandler handler = new RequestHandler(req);

handler.ExecutionComplete +=

new ExecutionCompleteDelegate(LoadComplete);

ThreadStartt ts = new ThreadStart(handler.Load);

Thread thread = new Thread(ts);

thread.Start();

}

private void LoadComplete(object sender, EventArgs e)

{

RequestHandler handler = (RequestHandler)sender;

Session["requestObject"] = handler.RequestObject;

}

Which just seemed like too much work, and tied way to much business logic in the UI, right where I don’t want it. I needed this to work in many, many places, but wanted to modify as little code as possible, and of course wanted it to be as resuable as possible.

The stickler is that the app has to be able to either give an object back to a page, or store it somewhere the page can get to it. I didn’t particularly like the idea of tying myself to Session variables, and in fact part of the requirements were that we not tie ourselves to session variables.

Since what I needed to do was find an object, I started thinking about a Registry1. From Martin Fowler’s PoEAA:

Registry: A well-known object that other objects can use to find common objects and services.

So if I could find a way to create a repeatable, resuable way to check for objects in the registry, and load them into the registry when they were done loading, I could use that as the pass through. The sketch in my mind looked like:

FindObject(params) <- Will always return an object
if object is loaded

use object

otherwise

tell object to register itself when done loading

load object

The first thing I needed was an object that knew how to load itself:



public class RequestObject

{

public void Load()

{

if(!isLoading)

{

isLoaded = false;

isLoading = true;

RequestHandler handler =

new RequestHandler(this);

handler.LoadComplete +=

new LoadCompleteDelegate(LoadComplete);

ThreadStart ts = new ThreadStart(handler.Load);

Thread thread = new Thread(ts);

thread.Start();

}

}

public void LoadComplete(object sender, EventArgs e)

{

RequestHandler handler = (RequestHandler)sender;

RequestObject result = handler.RequestObject;

result.IsLoaded = true;

result.IsLoading = false;

RequestObjectRegistry.Register(result);

}

}

Now I needed the registry the objects could use to register themselves and other objects could find them at. In this case I used the Application Cache, but I could modify that to be a session or even a static hashtable.



public class RequestObjectRegistry

{

public static void Find(RequestObject obj)

{

string cacheName = obj.ID.ToString();

Cache cache = System.Web.HttpContext.Current.Cache;

if(cache[cacheName] == null)

{

Register(obj);

return obj;

}

else

{

return (RequestObject)cache[cacheName];

}

}

public static void Register(RequestObject obj)

{

string cacheName = obj.ID.ToString();

Cache cache = System.Web.HttpContext.Current.Cache;

//overwrite any existing objects

cache[cacheName] = obj;

}

}

Finally I needed to make use of all this in my web and WAP pages. Because we use .NET’s code-behind pages, it’s fairly straightforward to have the logic be shared by the HTML and WAP versions of the page.



protected void Load_Page(object sender, EventArgs e)

{

if(!Page.IsPostBack)

{

if(Request.QueryString["ID"] != null && Request.QueryString["Name"] != null)

{

DisplayResult(Request.QueryString["ID"], Request.QueryString["Name"]);

}

}

}

private void cmdSubmit_Click(object sender, EventArgs e)

{

DisplayResult(ID.Text, Name.Text);

}

private void DisplayResult(string id, string name)

{

RequestObject obj = new RequestObject(id, name);

obj = RequestObjectRegistry.Find(obj);

if(obj.IsLoaded)

{

DisplayResult(obj);

}

else

{

WriteLoadingCard(id, name);

}

}

All in all it works very well, and is highly reuable for us.

1 thought on ““Your Request is Processing””

  1. amzonian says:
    September 25, 2009 at 12:53 pm

    Hi,

    I tried to add image but I don’t know how to do this
    Can anyone be kind to tell me how?

    thanks a lot

Comments are closed.

© 2025 Cory Foy | Powered by Superbs Personal Blog theme