Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Asynchronous Processing and Queuing with MSMQ or not?


:P
On this page:

I’m thinking out loud here about handling asynchronous requests in ASP.NET. I have an application that is running some pretty hairy and fairly lengthy (read about 2-3 minutes) reports which can be fired simultaneously by a number of users. What I’m after here is basically to start a request, pass it off to an external process (or machine) for processing, have the Web app check for a response, notify the user of progress and then eventually return a result back. All this without locking up an ASP. Net thread.

 

This is actually a fairly common scenario, so while I’m building this I want to extend my page framework to support this in a reusable fashion eventually.

 

ASP. Net is fairly forgiving for managing simultaneous request in most cases, but when you run a report like the above there’s bound to be a problem in any kind of a load scenario should it ever arise. In addition, in this case this happens to be a semi public link there’s always the chance that users will click multiple times by going back and resubmitting reports. In short, there’s a potential scalability problem.

 

A long while back I created a class to handle this sort of scenario for my FoxPro based West Wind Web Connection framework and I wrote about this process in an article. In this article I discuss a database driven approach to queuing requests and processing them with an external application that can live either locally or on another machine. This process has worked very well for me and a number of customers who've used in a number of fairly large applications.

 

As I sat down to tackle this problem in ASP. Net I wanted to review what options are available. ASP. Net actually supports mechanisms for running requests asynchronously through Async Handlers. Both plain HTTP handlers and the Page object for the WebForms engine support asynchronous processing. Unfortunately for load based scenarios this options don’t provide any relief as the threads used for these async handlers come from the same pool of threads that ASP. Net uses to process requests in the first place. So while you can ‘offload’ processing to threads outside of the ASP. Net thread queue, you’re still using the same pool of threads. In other words this doesn’t even buy any more threads, nor does it really address the scenario where you might want to dump processing off onto another machine because the local CPU(s) can't handle the processing load.

 

You can however fire off new threads from these Async HTTP handlers and manage these threads on your own and notify ASP. Net when your thread is done processing. This is a little better but this process is not pleasant to work with if you want to build a reusable scenario, and it doesn’t address the issue of offloading either.

 

Given that pure threading isn’t going to solve this problem the next option would be some sort of queuing mechanism. I’ve worked with MSMQ on a number of occasions and while it works in some scenarios I’m not sure if it is a good fit in this one. Queuing works great for pure ‘Call and forget’ interfaces where you submit something to a queue and the queue entries get picked up by another process at a later time. For this sort of thing MSMQ is easy and very efficient. But if you now need to return a response of some sort back to the caller (usually a polling caller) the process gets very messy. I’ve done this in the past with a Response queue which is then queried by the caller for a result. It works but it requires extra setup, a fair amount of code and it can easily introduce transactional problems if events fail to send responses which further complicates this process.

 

Another alternative for responses are Queued Events which can give some sort of indication that a process has completed, but given a stateless client like a Web Request, this sort of thing is really useless. In addition this works through COM+, which means you’re getting into COM interop – something I would much rather avoid if I can at all help it in a .NET application.

 

In fact, I’ve been wondering about MSMQ as a two way communication mechanism ( Request – Response asynchronously) and my conclusion is that while you can make MSMQ work for this with multiple queues (input and output) the process to do this is neither clean nor efficient. MSMQ doesn’t like to retrieve messages in random, non-queued order and making it work in a scenario where you need to send a response back ends up being quite a bit of work.

 

I haven’t worked with MSMQ that extensively, I’m curious if others share this point of view or can point at other approaches that I may have missed here…

 

One more thing that really sucks about MSMQ is the fact that messages are limited to 4megs. The first application I built with MSMQ together with Markus for a freight company dealt with forwarding Web Requests from one Web server to another over a WAN that was unreliable and often not available. These requests basically allowed queing incoming Web requests in the case where the connection to the remote was down. When the connection would come back up the other end would then pick up the queued requests and process them. Problem there is that request responses could be any size and we pretty quickly hit the 4 meg barrier. The code that had to split messages (and check whether a message was a split message) was a pure nightmare and involved having to package every single message into a header wrapper…

 

I wonder why, oh why there’s this 4 meg limit? I suspect it has to do with the optimization of the messages and large messages clogging the performance, but still if 4 megs are exceeded in messages MSMQ becomes a drag immediately.

 

Soooo… this makes me think that for this sort of Asynchronous processing with response requirements a Database message system is actually a much better approach. For one there’s no 4 meg limit. And with a database you have much more control over the actual inbound queue items including the ability to provide feedback that both the client and server can read and use to communicate with each other. For example, there could be status messages that are set by the processing server, that get routed back to the client that can get displayed on the next page refresh for the user. There’s also the ability to quickly search requests and possibly keep them around for review or possible later playback – another thing that would be difficult to do with MSMQ.

 

The idea is that there is one 'event' in the database that is identified by ID that both server and client can look at. The Client submits and the server picks up the first event. But the server can then write back into this 'pending' event and update information and return a response of some sort. It works both for the true Async scenario as well the Async request-response scenario, that is not such a good fit for MSMQ.

 

The downsides would be that it's a non-standard component and you need a database (SQL Server most likely to make sure the transacting works properly). And you lose some of the transaction features of the Queue, although that would be relatively easy to handle with completion marks.

 

I haven’t written any code for this component yet, but I am about to do this and it’ll likely be similar to the old Fox code I have. I’ve used this mechanism in the past and it’s worked reliably. The main difference likely will be though that the data stored will be serialized (much like the Messaging classes in the CLR) instead of only dealing with Text or ‘raw data’ (Text, Html, XML, or binary).

 

But I’m still wondering if there’s not something in the system that provides this sort of functionality more generically…

 

Any thoughts?

 

 


The Voices of Reason


 

Kevin Pirkl
November 15, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

FWIW I had posted a big long winded bit of information but this thing blocked the comment due to length restrictions so I will just dump you the links.

Fritz Onion & DevelopMentor - An ASP.Net Page Base class that provides custom thread pool mechanism & page base class derived from IHttpAsyncHandler
http://msdn.microsoft.com/msdnmag/issues/03/06/Threading/default.aspx

An HTTP handler http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=673

Use a handler to report where the free thread is at while it is working.

Use the IHttpAsyncHandler to free up the page for processing other requests.

Use something like remote scripting http://www.ashleyit.com/ to query the progress bar for percent complete. I converted this one a while back to ASP.Net http://www.gotdotnet.com/Workspaces/Workspace.aspx?id=be32e9ce-33be-4ef1-9f66-870f4131cd6f It's entitled JavaScript Remote Scripting (JSRS) For ASP.Net if you can't use the link above to get to the WorkSpace.

Kevin Pirkl
November 15, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

BTW a while back I looked all over for a MSMQ style replacement and had no luck. I must have looked over a gazillion links with no good finds. Sorry for the second message spam.

Mike
November 16, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Have you looked at the Async App Block?

-Mike

Jay Schumacher
November 16, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?


I have used MSMQ quite a bit recently, and for the most I agree with your assessment that it is typically best for a "send and forget" model. FWIW, MS uses MSMQ under the hood in some of the Smart Client stuff they have done (connected/disconnected clients). But as you mentioned, you need to monitor for responses. Really, the strength to me is that it transparently handles lack of connection, network latency (since the App is writing output locally), etc..

One other note is that I implemented a search mechanism using PEEK, and then READBYID methods which allowed the receiving application to process messages in any order it wanted. The PEEK would access the message, check various properties, and then use the ID if it was a match in the READ statement. While it took some extra time to write the code, it works great, and has never presented a performance issue to me (approx 35000 messages a day).

Rick Strahl
November 16, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Kevin, I actually was referring indirectly to Fritz' article in the Async stuff. It's cool that you can do this but for the most part it doesn't really solve the problem of async requests that might (and usually do) need to run on another application server. For this threading alone isn't going to work. Managing the UI portion of things is fairly straight forward and there are lots of ways to do that - one of which is mentioned in the Fox article referenced which uses META REFRESH to poll the server in short spurts to check for completion.

Mike, haven't looked at the Async block but it was my understanding that it too dealt primarily with threading scenarios, not remote async operation.

Jay, I've done the same thing with the PEEK mechanism - it works, but as you say it's clunky code and not optimal for MSMQ because now you are responsible for making sure that no two items are looking at the same thing or that things haven't popped off the queue in another way.

You make a very good point though about the online/offline capabilities of MSMQ which could not be so easily duplicated using a database. If that's not an issue though it still seems to me a central database would be much more flexible for sending the actual event messages because you can use a single record to trace a message through the system as opposed to scattering things into separate queues which for tracing, debugging or plain arhiving purposes is a nightmare.

Jay Schumacher
November 16, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?


Completely agree - if you aren't looking for the disconnected support, there is no reason not to use a database driven approach - for all of the reasons you mentioned.

In a sesnse, this is similar to using an EAI tool like BizTalk to manage processes and business transactions centrally, just on a smaller scale. Definitely a solid approach.

Maurice de Beijer
November 16, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Hi Rick,

Have you ever considerd doing this using a file drop in a directory. I have done so in the past to have .Net communicate with VFP and it worked very well. The basic setup is three directories (Request, Response and Processing) and the SystemFileWatcher object and the COM equivalents to see when a request or response is written. This works over a network between different machines and is very fast.


Rick Strahl
November 17, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Maurice,

Interesting idea. I suppose that could also work in the same way as a database, although you would not be able to have a good way of attaching additional information to a request in process. Also there's the potential issue of multiple clients looking at the same file or getting notified at the same - well, Ok that's easy to fix by locking the file immediately and clearing it after done to insure.

Seems like this would be a good way to go if you need notification of when files arrive which applies mostly to client applications, rather than request/response based server apps!

Maurice de Beijer
November 18, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Hi Rick,

I have used this with an existing application that had a file drop mode to make it available through a web service. Basically the application (could be multiple instances) wait for a request, rename the file to avoid multiple processes doing the same request and writing a response file (same name, different extension). The web service just waits for the response file to be written are returns the request. Using one Web Service and multiple VFP application processing request on separate machines you can get quite a scalable solution.

All request and response files are XML so I can add as much extra info as I want and when the response is read both files are moved to a backup directory so I can replay or debug requests.

The main advantage over a database system is the fact that you can use the SystemFileWatcherSystemFileWatcher object in .Net and the FindFirstChangeNotification API function in VFP to get notifications of request instead of having to poll a database for new records.

Rick Strahl
November 18, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Maurice, behind hte scenes hte OS is still doing some sort of polling even if it's hidden behind wait handles. In VFP this means you still have to poll since you can't run the handle checks in the back ground on a separate thread. In .NET or other multithreaded environment I would do the checking on a seperate thread and then raise an event on completion fired back to the main thread.

The advantage is that you don't need to have anything installed - this works without a data base or anything else since this is essentially an OS service.

Maurice de Beijer
November 19, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

I don’t know how Windows handles this internally but I agree that somewhere along the line there is bound to be some sort of polling involved. The advantage is the polling happens really low down and we don’t have to be aware of it and that makes it fast. Checking for a file rename and opening it exclusively will frequently result in a lock error because the rename action still has a handle on the file :-(

Anyway just an idea I thought you might be able to use.


Kevin Pirkl
November 22, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Ok if your looking for asynch requests that would run on another application server then you might want to take a look into Yukon's Service Broker technology. It puports internal or external processes to send and receive guaranteed, asynchronous messages. Messages can be grouped into tasks to prevent cross server processing and the triggered servicing side of the equation supports either T-SQL or one of the CLR-targeted languages. Here are a couple of links that intrigued me anyhow. http://msdn.microsoft.com/msdnmag/issues/04/02/YukonBasics/default.aspx and http://download.microsoft.com/download/3/8/1/38154d73-bc47-4e9f-a7f5-ca9beb118fde/Chapter15_w.pdf

Hope this helps.

Rick Strahl
November 22, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Kevin, yeah this looks interesting and is right along the lines of what I was proposing at the start of this post <g>. The key thing here is that the 'broker' must have hte ability to correlate messages easily which it looks like this service will do. Will need to take a look at the details of how this service is accessed. It looks like htere's a ton of gunk there that's more than a little overkill for most scenarios.

Michele Leroux Bustamante
November 23, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Hi Rick!

Funny I happened to read this post, as I'm giving a talk on distributed applications tonight at the local user group. Hope to see you at SDGN next year :)

Regarding your statement:
In addition this works through COM+, which means you’re getting into COM interop – something I would much rather avoid if I can at all help it in a .NET application.

Although this has been poorly documented all over the place, in fact, when you write a serviced component in .NET (a COM+ EnterpriseService component) you are not invoking the component over COM interop. There are a very low set of COM+ services that are invoked through optimized interop channels but ONLY the services are accessed via interop (like transactions, RBS, encryption).

So, your requirement to invoke this in another process, or on another machine, is best handled by a serviced component, running as a separate application. This will give you the ability to configure runtime process identity for the component to talk to the database, support message encryption, and transactions as needed. Furthermore, you can distribute it to another machine (or not) as needed.

This is also the programming model we'll use in Indigo, so it has a migration path as well.

Cheers!
-Michele

Rick Strahl
November 23, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

Hey Michelle,

Any pointers where to get more info on Async eventing with ServicedComponent? Did a quick search and not much came up. Truthfully, I'm not all that familiar with COM+ through .NET, but even in the COM world Async events and Queued Components were a PITA and didn't work all that reliably. Too much of a headache to set up and configure. It's possible though that if .NET provides a way to do this that this becomes easier.

I guess we had this discussion before <g> - I'm not a big fan of COM+ except when you really need the features it provides. I'm not sure that here it would be the right fit. Maybe you can give a better idea of what you're thinking of?

Kevin Pirkl
November 27, 2004

# re: Asynchronous Processing and Queuing with MSMQ or not?

MSDN WebCast Dec 8th. A bit off but should give more information. http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?eventid=1032263310&culture=en-us

Madhusudan
May 29, 2008

# re: Asynchronous Processing and Queuing with MSMQ or not?

Hi,

If i will send a message to a queue and suppose the system to which i m sending the message is not connected currently to the network,i will not get the response.Now the system will be connected i will get the response.Hence, the sending system cannot wait for the response to come it will continue its work and when the response will come from the recipient ,the sender will respond to it.Here is my question how can i receive a response message asynchronously.

Thanks'
Madhusudan

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2025