Developing Cloud Applications with Windows Azure Storage: Blobs

  • 3/15/2013

Blob leases

Windows Azure storage provides a locking mechanism called a lease for preventing multiple parties from attempting to write to the same blob. A blob lease provides exclusive write access to the blob. After a lease is acquired, a client must include the active lease ID with the write request. The client has a one-minute window from the time the lease is acquired to complete the write; however, the lease can be continuously renewed to extend this time indefinitely to meet your application’s needs.

A lease request may be performed in one of four modes:

  • Acquire Request a new lease.

  • Renew Renew an existing lease.

  • Release Release the lease, which allows another client to immediately acquire a lease on the blob.

  • Break End the lease, but prevent other clients from acquiring a new lease until the current lease period expires.

Taking a lease on a blob can also be used as a very convenient and inexpensive locking semantic for other cloud operations. For example, one Windows Azure Cloud Services instance might take a lease on a blob as means of signaling other instances that the resource is busy. Other instances would then be required to check for the existence of a lease before proceeding with a competing operation. If a lock is present, the competing operation can be held in a loop until the blob lock is released. When used in this manner, the blob lease acts as a traffic light. The competing instances stop when the traffic light is red (for example, the lock is present) and proceed when it turns green (for example, the lock was removed).

The following HTTP PUT request demonstrates how to acquire a lease on a blob. The query string comp=lease sets up the operation. The action to be taken on the lease is transmitted via the x-ms-lease-action HTTP header, as the following example demonstrates.

PUT http://azureinsiders.blob.core.windows.net/demo/test.txt
    ?comp=lease&timeout=90 HTTP/1.1
x-ms-version: 2012-02-12
User-Agent: WA-Storage/2.0.0
x-ms-lease-action: acquire
x-ms-lease-duration: 30
x-ms-date: Wed, 26 Dec 2012 08:36:22 GMT
Authorization: SharedKey azureinsiders:YsBInVJ6NhkAIgkuUk9647JbpEthVnZR1WA0cYRM1Hc=
Host: azureinsiders.blob.core.windows.net
Content-Length: 0

In the following Windows Azure client library code, you call the AcquireLease method on a blob and then show the blob’s contents in Internet Explorer to prove you can perform reads against blobs that have leases. Immediately after, you attempt to acquire a second lease on the same blob. Always wrap your attempts to acquire a lease inside of a try/catch block, and always confirm that the WebException’s status code is a Conflict status code, because the WebException could have been caused by any one of a number of possible conditions.

String leaseId = blob.AcquireLease(TimeSpan.FromSeconds(30), null);

// Succeeds: reads are OK while a lease is obtained
Process.Start("IExplore", blob.Uri.ToString()).WaitForExit();

// Try to acquire another lease:
try {
    leaseId = blob.AcquireLease(TimeSpan.FromSeconds(30), null);
}
catch (StorageException ex) {
    if ((HttpStatusCode)ex.RequestInformation.HttpStatusCode !=
          HttpStatusCode.Conflict) throw;
    Console.WriteLine(ex.RequestInformation.HttpStatusMessage);
}

You next demonstrate that the lease prevents writing to the blob until you supply a valid lease ID.

// Fails: Writes are not OK while a lease is held:
try {
    blob.UploadText("Can't upload while lease held without lease ID");
}
catch (StorageException ex) {
    if ((HttpStatusCode)ex.RequestInformation.HttpStatusCode !=
          HttpStatusCode.Conflict) throw;
    Console.WriteLine(ex.RequestInformation.HttpStatusMessage);
}
// Succeeds: Writes are OK if we specify a lease Id:
try {
    leaseId = blob.AcquireLease(TimeSpan.FromSeconds(30), null);
}
catch { } // Ensure we have the lease before doing the PUT

To release the lease on a blob via the RESTful API, simply execute another HTTP PUT against the blob’s URI by using a query string parameter comp=lease, and set x-ms-lease-action to Release, as shown here.

PUT http://azureinsiders.blob.core.windows.net/demo/test.txt
    ?comp=lease&timeout=90 HTTP/1.1
x-ms-version: 2012-02-12
User-Agent: WA-Storage/2.0.0
x-ms-lease-id: a9053786-c96e-4bb9-8711-477fbd7fcb03
x-ms-lease-action: release
x-ms-date: Sun, 30 Dec 2012 02:29:22 GMT
Authorization: SharedKey azureinsiders:LJEakr84hNV6nStrTAgBzZdo3k50GlHy3f2syVuRrEM=
Host: azureinsiders.blob.core.windows.net
Content-Length: 0

To release a blob using the Windows Azure client library, call the ReleaseLease method and pass in the lease ID, as shown in this code snippet.

blob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId));
Process.Start("IExplore", blob.Uri.ToString()).WaitForExit();

Finally, after you have released your lease on the blob, you can update its contents to demonstrate how the lease is no longer preventing writing to the blob. You bring the contents up in the browser to visually verify that the contents were updated.

blob.UploadText("Data uploaded while lease NOT held");
Process.Start("IExplore", blob.Uri.ToString()).WaitForExit();