RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Optimize ASP and IIS by Decoupling Long-running Requests : Page 4

Lengthy Web requests, such as those that process and format complex reports, tie up threads from the ASP thread pool. When the number of ASP requests exceeds the number of available threads, you'll see a dramatic slowdown in response time. To solve the problem, you have to make your ASP pages run faster. And to do that you need to decouple the background request processing from the requesting ASP thread. Here's how.

Exploring the Code
The code for the solution is really quite simple. The code below demonstrates the ease with which you can queue a message using MSMQ. The first step is to create a GUID for the unique message ID. You'll find the code in the GUID_Generator project in the GUIDGen class included in the downloadable source.

Here's how the ASP script calls the NewGUID() method:

   '---- create a GUID to uniquely identify the message
   Set objGUID = Server.CreateObject("GUID_Generator.GUIDGen")
   strMsgID = objGUID.NewGUID()
Next, the script opens the MSMQ queue.

   '---- open MSMQ Queue for sending request message
   Set objQueueInfo = Server.CreateObject( _
   objQueueInfo.FormatName = _
   Set MSMQ_QueueSend = objQueueInfo.Open( _
The preceding script fragment creates an MSMQ.MSMQQueueInfo reference using a direct format name to identify the queue—the "OS:." notation indicates that the queue is located on the local machine.

The last section of the code creates a message, sets the message body to the unique message ID, and then sends the message to the queue that was opened.

   '---- send message
   Set objMsg = Server.CreateObject("MSMQ.MSMQMessage")
   objMsg.Body = strMsgID
   objMsg.Send MSMQ_QueueSend
In practice, the GUID would comprise only a small portion of the request information being sent to the resource, but this example serves to illustrate a simple solution. Finally, the user is redirected to an intermediate page that polls for a response from the resource server.

   '---- redirect user to intermediate wait page
   Response.Redirect _
      "Response_Intermediate_Wait.asp?MsgID=" & strMsgID
For the purposes of illustrating a simple solution, I have included the code for a resource server that 'listens' on the queue that the requests are sent to. The server uses an event-driven mechanism provided by MSMQ to receive notifications of new messages in the queue. When a new message arrives, the server removes the message from the queue, and immediately writes the GUID to a SQL table, which will be the signal to the intermediate page that the resource server has responded to the request. Again, in practice, the data written to the table would be considerably more elaborate to support the needs of the application. You can download the code here.

At this point, it is important to mention that the resource server application is the key to making the call asynchronous for the Web page. By allowing the ASP page to simply submit the request to an external process, in this case executing in Visual Basic, it is freed from the requirement of waiting on the response to return, as was the case when the ASP script executed synchronously. This is very similar to the way operating systems block a thread waiting for a response from I/O reads. Blocking the waiting thread allows the operating system to go on executing other waiting threads—when the read completes, the thread is reawakened and is allowed to go on executing. In a very similar way, this solution allows the operating system to make better use of its available resources and increase overall throughput of the system.

When running, the ASP pages generate the sequence of client-side displays shown in Figure 2, Figure 3, and Figure 4.

Figure 2. Make a Request: Clicking this button will run the ASP script that generates the unique message ID, and sends the message to the resource server using MSMQ.
Figure 3: Waiting for Response. After making a request, users see this page, which refreshes itself every 2 seconds, looking for its response from the resource server application.
Figure 4. Request Completed: When the server finishes processing the response, the "wait" page retrieves the content from the database and displays the results to the user.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date