Simple Capped Exponential Back-Off for Queues

Recently Steve Marx and I spent a few hours working on a best practices document for Windows Azure. As expected, this was a fun and educational experience – plenty of goofing around, but also some really good discussion on things to think about when building applications for Windows Azure. One of the items we discussed is a better approach for sleeping inside the Worker Role when pulling from queues. Rather than defaulting to a retry every 10 seconds we decided that the best approach is to exponentially back-off on your queue reads while capping it with an upper bound.

The primary value of this is to decrease the number of storage transactions when reading from your queue, and therefore reduce both bandwidth and transaction costs.

There are plenty of other good posts on this topic that provide a lot more detailed justification and rationale for this approach:

The logic and approach is deceptively simple and I thought I’d share a really simple, yet effective, example. (Incidentally, credit goes to Steve for very quickly putting together the basis of this really simple example.)

Here’s the code:

   string queueName = "queuetest";

   int minInterval = 1;
   int interval = minInterval;

   int exponent = 2;
   int maxInterval = 60;

   CloudStorageAccount account = CloudStorageAccount.DevelopmentStorageAccount;
   CloudQueueClient queueClient = account.CreateCloudQueueClient();
   CloudQueue queue = queueClient.GetQueueReference(queueName);
   queue.CreateIfNotExist();

   while (true)
   {
      var msg = queue.GetMessage();
      if (msg != null)
      {
         // do something
         queue.DeleteMessage(msg);
         interval = minInterval;

         Trace.WriteLine(string.Format("Interval reset to {0} seconds", interval));
      }
      else
      {
         Trace.WriteLine(string.Format("Sleep for {0} seconds", interval));
         Thread.Sleep(TimeSpan.FromSeconds(interval));
         interval = Math.Min(maxInterval, interval * exponent);
      }
   }

As I said, really simple. The magic is in the last line where we check to see which is smaller – the maximum interval or the product of the interval and the exponent. At some point the product of the interval and exponent grows larger than the maximum interval, and consequently the interval value is set to the maximum interval.

Here’s the output in the Windows Azure Compute Emulator:

   Sleep for 1 seconds
   Sleep for 2 seconds
   Sleep for 4 seconds
   Sleep for 8 seconds
   Sleep for 16 seconds
   Sleep for 32 seconds
   Sleep for 60 seconds
   Sleep for 60 seconds
   ...

Now, the application will continue to sleep until it finds a message in the queue, at which point the interval is reset back to one. To test this I used the Azure Storage Explorer and created a new queue message.

AzureStorageExplorerQueue

Once the message is created the output is as follows:

   Interval reset to 1 seconds
   Sleep for 1 seconds
   Sleep for 2 seconds
   Sleep for 4 seconds
   Sleep for 8 seconds
   ...

And so forth.

You can find all the source code for this sample in my CappedExponentialBackOff repository on GitHub.

Pretty simple but quite useful. I hope this helps!


Return Empty Set Instead of ResourceNotFound from Table Storage

This past week I’ve been working on a little project – amazing how less email equates to more time for other endeavors – and I was surprised when I received a DataServiceQueryException when querying table storage in the local storage emulator. I was querying based on partition and row keys and, if no data matched the statement, I received an HTTP 404: Resource Not Found exception.

I was initially puzzled. Shouldn’t I receive an empty set or null instead?

Of course, I had forgotten that this is by design. The DataServiceContext will throw a DataServiceQueryException if there’s no data to return. To receive an empty set it’s necessary to set the IgnoreResourceNotFoundException property to true.

Here’s a simplified version of the code:

    string connectionString = "UseDevelopmentStorage=true";

    var context = CloudStorageAccount.Parse(connectionString)
        .CreateCloudTableClient().GetDataServiceContext();

    context.IgnoreResourceNotFoundException = true;

    var results = context.CreateQuery<TableEntity>("tableName")
        .Where(e => e.PartitionKey == partitionKey && e.RowKey == rowKey).AsTableServiceQuery();

    var key = results.FirstOrDefault();

Problem solved. No DataServiceQueryException!

Something to keep in mind when working with the Windows Azure table storage service. I almost didn’t blog about but decided that it was worth a few minutes effort. Probably something to add to your Windows Azure development checklist (you have one, right?).

Joining Aditi Technologies as Chief Technology Officer

It’s been a little more than three weeks since I announced my departure from Microsoft. Leaving Microsoft was harder than I expected and I never anticipated the outpouring of support and appreciation from everyone. From the bottom of my heart, thank you!

Aditi TechnologiesToday I’m really excited to share that I’ve joined Aditi Technologies as Chief Technology Officer. Aditi is a top Microsoft partner with a lot of talented people and has recently made a lot of key investments – particularly around Windows Azure. Last November Aditi acquired Cumulux, hired Windows Azure MVP Nuno Godinho, and most recently brought on the former Windows Azure Tactical Strategist Steve Marx.

Aditi has a cloud-first strategy that I find compelling. Brian Hanna – Director, Cloud Practice – summarized it nicely here:

"We believe that cloud and consumerization will drive future technology strategies and standards. We encourage our customers to consider a ‘cloud first policy’ for every technology project. While the approach might be radical, we believe that by investing in the cloud ahead of the curve, customers stand to gain significant competitive advantage in the long term."

My leaving Microsoft to join Aditi is a testament to the depth to which I agree with this statement. Yet, while cloud is an area with which I remain passionate, as CTO I will also focus on technologies across our software practices – including digital marketing, enterprise social, IT/virtualization, and BI/analytics. This means I’ll work with SharePoint, SQL Server, AD, Hadoop, and so many other great technologies! At the end of the day, my charter is to build our global engineering capabilities across the company – cloud may be a foundation but there are a lot of other areas with which to dig in!

This is going to be an exciting journey.

To learn a bit more you can read the my official appointment announcement and visit Aditi management page.

Leaving Microsoft

I’ve spent a fair amount of time thinking about the right title for this post. Steve Marx was clever with Career vNext, Sriram Krishnan waxed poetic with On Leaving Microsoft, and Brad Abrams just came out and talked about My Last Day at Microsoft. Yet no matter how it’s phrased it comes down to one thing: leaving Microsoft.

I can honestly say that I never thought this day would come. Working for Microsoft has been a dream come true – brilliant colleagues, interesting opportunities, and inspiring technologies. In particular, I’ve had a blast working on Windows Azure. I never envisaged that a little project I worked on in 2008 would lead me to Redmond and all the interesting things I’ve done over the last several years.

Fortunately for me (and I hope for you), I am not going far from Windows Azure. I’ll share more details soon but for now I’ll just say that I’m going “to put money where my mouth is” and help companies build real solutions on Windows Azure. This is going to be an amazing year for Windows Azure and I plan to push it to the limit!

Don’t hesitate to reach out to me – I’d love to stay in touch.

Thanks for the ride!

Cannot create database ‘DevelopmentStorageDb20110816′ for the Windows Azure Storage Emulator

Have you seen this error before? If you’ve spent any time with the Windows Azure storage emulator it’s highly probable. Here’s the full text:

    Added reservation for http://127.0.0.1:10000/ in user account COMPUTER\User.
    Added reservation for http://127.0.0.1:10001/ in user account COMPUTER\User.
    Added reservation for http://127.0.0.1:10002/ in user account COMPUTER\User.

    Creating database DevelopmentStorageDb20110816...
    Cannot create database 'DevelopmentStorageDb20110816' : CREATE DATABASE permission
    denied in database 'master'.

    One or more initialization actions have failed. Resolve these errors before attempting
    to run the storage emulator again. These errors can occur if SQL Server was installed
    by someone other than the current user. Please refer to
    http://go.microsoft.com/fwlink/?LinkID=205140 for more details.

And an image of the error:

Development Storage initialization error

This error can occur when running the storage emulator (or running DSINIT.exe) for the first time. The compute emulator needs to initialize itself, which includes creating a local SQL Server database that is used to store data for local Windows Azure storage. The above error indicates that there’s a permissions when trying to create the database.

There are a number of ways to resolve this issue and, like others, I have my favorite approach. I have a script that I run which will add the executing user to the SQL Server sysadmin role.

I’ve published the entire script here: https://gist.github.com/1677788. Simply download and unzip the file. Open up an elevated command prompt and execute the file (i.e. run addselftosqlsysadmin.cmd). Once the script is executed the user can successfully initialize the storage emulator.

I hope this helps!