2

I have an Azure web application that sends messages to a Azure queue and I have workers that poll the queue and process the messages as they become available. For the most part, this is working fine and I am satisfied with this design.

However there is one scenario where it is not working so great and I looking for suggestions on how to handle this specific case:

Once in a while, a particular user (let's call him Bob) will perform a few actions that result in several messages being sent to the queue which creates a backlog and other users have to wait for Bob's messages to be processed before their messages are processed. They are penalized for the fact that Bob sent many messages in the queue.

How can I improve my design to prevent messages for one user do not cause messages for other users to be delayed? My first instinct was to create one queue for each user but if I have a few thousand users, I'm not sure it's a reasonable design.

Are there any design patterns that exist to address this scenario? If so, are there any C# implementations of the pattern I could reuse?

desautelsj
  • 3,587
  • 4
  • 37
  • 55
  • 1
    What's the desired behavior? You want Bob to wait instead of other people? In other words, if the queue is ABBBCDEF (each letter represents a message by that user), in what order should the messages be processed? ABCDEFBB? What if message G comes in after you've processed ABCDEF? Now that the queue is BBG, do you process G first? Or B? How many Bs? – user94559 Oct 01 '12 at 20:13
  • To add a suggestion, perhaps you want to do rate limiting. Only process a message from Bob if you haven't processed any other messages from Bob in the past 30 seconds? – user94559 Oct 01 '12 at 20:14
  • The desired behavior is that ABCDEF are processed before another B is processed. When G comes in, I expect it to be processed before other B. When G is processed, we can resume processing as many B as possible. Your idea of rate limiting is interesting. Do you know of any C# implementation? – desautelsj Oct 01 '12 at 22:10
  • Your answers tell me that you need to know the history, not just the current state of the queue, to know which to process. (When the queues is BG, you need to know that you've already processed a B recently.) Just an observation that hopefully helps. – user94559 Oct 01 '12 at 23:08
  • The simplest rate-limiting you could do is something like: `if((DateTime.UtcNow - getLastProcessed(user)) < TimeSpan.FromSeconds(30)) { process(user); setLastProcessed(user, DateTime.UtcNow) }` I'm assuming something like table storage to handle (get|set)LastProcessed. – user94559 Oct 01 '12 at 23:11
  • Does Bob perform several actions, each of which spawns a new queue message? Or does Bob perform one actions that spawns several queue messages? The latter case is probably easier to deal with. Also, you may want to investigate the general topic of "queueing theory", as some smart person has probably come up with a good answer for this already. – Brian Reischl Oct 01 '12 at 23:23

0 Answers0