Cloud Lesson Learned: Exponential Backoff

This blog is the first one of a series of blogs addressing programming practices and lessons learned related to cloud computing. While most developers will be familiar at least conceptually with the techniques exposed, I will provide background information and code samples in an attempt to explain why they are so critical in cloud software development.  While most of the information provided will be using Windows Azure and/or SQL Azure, these concepts apply to cloud computing in general.

Exponential Backoff

In this blog I will discuss expotential backoff (EB). EB is a retry technique that assumes failure by nature and attempts to retry the operation, with an exponentially increasing wait time, until a maximum retry count has been reached. This technique accounts for the fact that cloud resources may be unavailable more than a few seconds, for any reason out of your control. In the case of SQL Azure for example, a database may be moved to another server at any time, causing the database from being unavailable for a few seconds, or a few minutes depending on the scenario.

In addition to resource availability, EB also takes into account the fact that the cloud provider may decide to throttle, or limit, availability of resources due to usage overload. For example, requesting too many connection requests quickly may be viewed as a Denial of Service attack by the cloud provider. As result, backing off exponentially connection requests to SQL Azure provides a mechanism to scale back connection requests when a capacity threshold has been encountered.

Example

The following C# example shows an extension method called TryOpen that provides an EB when a connection timeout is encountered. In your code you may want to provide additional exception management, such as providing a mechanism to cancel the EB if a user presses a Cancel button for example. In this code snippet, the TryOpen method tries to open a database connection up to 5 times in a row, backing off 3 seconds exponentially every time (3 seconds, 9 seconds, 27 seconds...).

[the code below was edited on 6/4/11 to fix a bug in the sleep timeout calculation]

static SqlConnection TryOpen(this SqlConnection connection)
{
  int attempts = 0;

  while (attempts < 5)
  {
    try    {
      if (attempts > 0)       System.Threading.Thread.Sleep(((int)Math.Pow(3, attempts)) * 1000);      connection.Open();
      return connection;
    }
    catch { }
    attempts++;
  }
  throw new Exception("Unable to obtain a connection to SQL Server or SQL Azure.");
}

Finally, assuming the above code was placed in a static class, your primary code could simply use the TryOpen method this way:

SqlConnection connection = new SqlConnection("your_connection_string");
connection.TryOpen();

As you can see, hiding connection retries is simple when you leverage extension methods in .NET. This allows you to centralize rather complex routines that should be centralized for maintenance.

This article is part of the GWB Archives. Original Author: Herve Roggero

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.