Technique for post-response logging

I’ve built some custom analytics code that I’ve plugged into one of my sites. I need to use it sitewide and it should not delay the HTTP response. It should run as “clean-up” code after the response is sent to the visitor. After studying the forums and doing some internet searches it looked like an HTTP module would cover both requirements, and it does neatly take care of all pages across the site. However, it seems pretty clear that the code in Application End_Request, is causing a delay in sending the HTTP response to the visitor.

How can I call my analytics class after the HTTP response is sent to eliminate these delays?

What you need to do is look at handling this in an asynchronous manner rather than trying to handle it after the request has been sent. The typical way one does this is by using a message queue of some sort. You grab what data you can quickly and push out a message. Message sits in a queue and gets processed in another app completely unrelated to your app, not interfering with the http pipeline.

Interesting. One recommendation I found in a blog was to build a web service - something which only makes sense to me after reading your reply. So the web service would be the “message queue / another app” and all I have to do is use my HttpModule to package up the information I want and send it to the URL of the webservice. Then allow the rest of the page cycle to continue. Is this correct?

Or is the idea to create some type of static object that stores the data and run some hourly process against it that clears out the queue and saves the data to my database?

I guess I’m still trying to figure out two issues. One is the nature of the message queue, I would like to use some type of in-memory structure to avoid calling external resources like my DB. I’m also wondering about the best way to package the info quickly so that I minimize the time my HttpModule has to hold things up.

Thanks,

WebService could work – but make sure to look at the APIs and use the FireAndForget attribute so it isn’t a blocking clalll – the HTTP request is more expensive than a database write in most cases.

Static object could also work but you run the risk of having a memory leak if you aren’t perfect at cleaning up,. A message queue is really a very fancy version of that concept, with lots of testing around edge cases to make sure messages get through. You should probably take a look at NServiceBus or MassTransit for examples of the current best of breed message queue implementations. Both are transport agnostic, you’ll probably us MSMQ as the backing store.

It would be pretty hard to measurably hold a http request up with processing, the writes to databases or services tend to be the bottlenecks processing-wise. Remember, timing-wise, the main thing is getting the message out of the way, not getting it fully processed in queue. You might just want to dump more raw data and push more work on the back-end process if performance is the main concern here.