Tuesday, April 12, 2011

How to efficiently read messages from a CloudQueue

While staying at the MVP summit in Redmond I could exchange ideas of code patterns in Windows Azure. One new pattern to me was to save money by reducing calls to a CloudQueue.

On first thought one would try to check for new messages on a queue every few seconds. But if there are many messages in the queue, waiting for several seconds makes you loosing expensive computing time. On the other hand, checking for new messages instantly without waiting results in many unnecessary (and expensive) calls to the Storage.

So there needs to be a way in between those two extremes. And there is one:
After having read a message from the queue, you instantly check again for another new message. If there are new messages, no unnecessary calls are made and all computing time is used for processing those messages.
If there are no new messages, you wait a little and check again. If there is still nothing in the queue, you wait a little longer and check again. Still nothing? Then wait even a little longer as the last time, because it seems unlikely that a new message will show up immediately. Step by step the waiting time is increased to a given maximum. This results in less calls when there is nothing to do.

And here is a code example:

  1: var maxPause = 60000;
  2: var minPause = 1;
  3: var pause = minPause;
  6: while (true)  
  7: {  
  8:     // read from queue
  9:      Console.Write("Reading from Queue... "); 
 10:      var msg = queue.GetMessage(); 
 12:      if (msg == null) 
 13:      { 
 14:         // no message could be read, so wait 
 15:         Console.WriteLine("nothing -> wait " + pause.ToString()); 
 16:         System.Threading.Thread.Sleep(pause); 
 19:         // update waiting time 
 20:         if (pause < maxPause) pause *= 2;
 21:      } 
 22:      else 
 23:      { 
 24:         Console.WriteLine("read."); 
 26:         // reset waiting time 
 27:         pause = minPause; 
 29:         // proccess message 
 30:      } 
 31: }

While writing this blog entry, I invented a class QueueSupervisor, that supervises a queue in the background and raises an event when a new message appears in the queue. You can download this class here: QueueSupervisor.zip

No comments:

Post a Comment