tags:

views:

368

answers:

1

I'm not sure how best to describe this, or the best title, so bear with me!

I'm using MSMQ to queue up a large number of commands that will fire off HTTP requests to various websites and APIs. In order to avoid hammering these services (and to stay within certain pre-defined request limits) I need to ensure tasks hitting the same domain are executed only after a minimum time has elapsed from the last request.

Previously I was using a database to queue the tasks, and so could perform a query to achieve this, but we rapidly outgrew that solution with the number of tasks (way too many deadlocks on the table).

Does anyone have any suggestions as to what approach we could take? I've considered just keeping taking items off the queue until you find one that you can execute - but I'm conscious there's nothing to stop the ordering on the queue meaning we could take off thousands for the same domain before finding one on a different domain.

Thanks!

+1  A: 

You 'outgrew' relational database and replace it with MSMQ? This is like 'promoting' from college to kindergarten! 4GB size limitation, no high availability solution, questionable recoverability, no querying of the message queue, you are already running into the very limitations than everyone is claiming when moving away from MSMQ to a relational database based queuing...

I highly recommend you go back to the table based queuing. There are ways to avoid deadlocks in table based queuing, specially with the advent of OUTPUT clauses for DELETE (which is the key to write a fast deadlock free dequeue operation from a table based queue).

Or you can use an off-the-shelf in database queuing solution like Service Broker. Actually SSB would offer a free lunch with many of its features, like built-in throttling (MAX_QUEUE_READERS), enable/disable processing on a schedule (by enabling/disabling activation), built-in timers for retry, high-availability based on database mirroring or on clustering, or built-in priority handling.

Remus Rusanu
Okay, that's interesting - we haven't thrown away our DB solution at all, just had ongoing deadlock issues, so we decided to investigate pro/cons of MSMQ! I will take a look at service broker.
James Crowley
SSB is an *acquired* taste ;) But user table, getting rid of the deadlocks is actually doable, I've been there, done that. I have in production system queues up/dequeues web calls at a rate of few hundreds per second, on a low end hardware, not a single deadlock in months now (in the queue processing). Is not *trivial* and requires good understanding of how a deadlock occurs and how it can be avoided, took me few weeks until all issues were ironed out and I had some unexpected surprises. But the control and customization beats MSMQ no question there.
Remus Rusanu
Yeah, now I'm looking into the details of it - not so pretty.I've tried to minimize our deadlocks, using upgrade locks on rows and various sorts, but to be honest my DB knowledge isn't cutting it at the moment, despite the reading around I've done.Do you reckon it would be worth trying to resolve our existing system (which has the functionality we need... ) just without the deadlocks, or switching to something like service broker?thanks for your advice!
James Crowley
Fix your existing system. You can seek expert advice to solve the deadlock issues if is beyond your knowledge (no shame in that, we all have different strengths). As I stated, a table based solution can outclass MSMQ on so many levels. Since you do not actually send any *remote* message, you solely use MSMQ as a queue data structure, and it doesn't deadlock because is *totally inflexible*. Your table deadlocks because it allows you to do so many more things compared to MSMQ and you rushed ahead in adding a lot of features probably.
Remus Rusanu