Windows Azure Queue Tidbit

Tuesday, August 23 2011

At a CINNUG meeting quite a while ago I was talking about the Windows Azure Storage subsystems: Queues, BLOBs and Tables.  While I was talking about Queues a question came up about using the Clear method on the CloudQueue object.  The MSDN Docs state: “The Clear method clears all messages from the queue”.   The question was, Does this also delete messages that are currently invisible (meaning a process has them taken them off the queue using GetMessage or GetMessages but has not deleted them yet)?  At the time I didn’t know the answer and said I would find out.  I even wrote a note to figure it out… which somehow ended up in the front of my notebook and completely forgotten. 

While I was sitting down at my laptop tonight this note slipped out of my notebook and reminded me that I still owe an answer to this.  I loaded up LINQPad and quickly set up some code to test this.  I created two queries in LINQPad.  One connected to a storage account, created a queue if it didn’t exist and added a message to the queue.  It also pulled the message from the queue with a timeout of about a minute then put the Thread to sleep for about a minute and a half.

Query One:

StorageCredentialsAccountAndKey credentials = new StorageCredentialsAccountAndKey(
	"somestorageAccountName",
	@"SomeStorageAccountKey"	);
CloudStorageAccount account = new CloudStorageAccount(credentials, true);
CloudQueueClient qClient = account.CreateCloudQueueClient();

CloudQueue q = qClient.GetQueueReference("sample");
q.CreateIfNotExist();

CloudQueueMessage msg = new CloudQueueMessage("Hello world");

q.AddMessage(msg);

CloudQueueMessage poppedMessage = q.GetMessage(TimeSpan.FromMinutes(1));

Thread.Sleep(TimeSpan.FromMinutes(1.5));

q.DeleteMessage(poppedMessage);

 

The second query connected to the same queue in the storage account and called Clear. 

Query Two:

//Same as above up to the creation of the queue reference.
CloudQueue q = qClient.GetQueueReference("sample");
q.CreateIfNotExist();

q.Clear();

 

I tested by executing the first query, which added a message and then pulled the message for processing, then immediately ran the second query.  At the end of the thread sleep in the first query the code attempted to delete the queue message which gave an error saying the queue message does not exist.

So yes, calling Clear does destroy ALL messages, even those hidden on the queue.  This does make sense as you are wanting to clear out the queue, but be aware that if you have code that has pulled a message for processing when Clear is called they will receive a StorageClientException (or a 404) when they go to delete that message from the queue.

The MSDN docs do mention that calling Clear on a queue that has a LOT of messages may timeout, in which case the client should retry to continue deleting the messages. 

On a side note, I was using http://myazurestorage.com to peek at the queue and contents as I was running this test and noticed that the ApproximateMessageCount property was returning 1 even after the message was grabbed off the queue, so it does take hidden messages into account.  Of course, as soon as I ran the second query this dropped to 0.