2187-just_azure.svg

In this post of my ongoing series on Azure Blob Storage I’m going to talk about Blob Leases and show you how to use them.

Think about what happens when you lease an apartment. You acquire a lease and they give you a key. Nobody else can use that apartment while you have the key. Other people can ask to lease the property, but the landlord has to refuse until you end the lease and give up the key. When the lease expires, you can renew the lease or release it and vacate the property. If you do something inappropriate during the lease and end up on Judge Judy, the landlord can break the lease and kick you out without having a key. This is very similar to how leases work in Blob Storage.

Blob Leases allow you to claim ownership to a Blob. Once you have the lease you can then update the Blob or delete the Blob without worrying about another process changing it underneath you. When a Blob is leased, other processes can still read it, but any attempt to update it will fail. You can update Blobs without taking a lease first, but you do run the chance of another process also attempting to modify it at the same time.

For example, let’s say you have shared files in a container in Blob Storage, and you support an application used to maintain those files. When one of your customers wants to update a file, you would try to acquire a lease on the Blob. If successful, you would then do the update. While doing the update, if another customer tried to update the file, their request for a lease would fail (409 error – conflict), and you could tell them the file is being updated by someone else.

Another use for a Blob lease might be as a distributed locking mechanism for a Master/Slave pattern where multiple nodes use the holder of the lease to determine who is the master. If the master node goes down the lease expires another node would then acquire a lease on the blob and thus become the new master of the cluster. This can be used to ensure that only one machine can perform a specific operation at a time, similar to a sync lock in C#.

When you take out a lease on a Blob, you can select either an infinite lease, or a timespan of 15 to 60 seconds. To select an infinite lease, set the timespan to zero seconds. The Blob Storage service returns a Lease Id to you if successfully acquire a lease. You can also provide your own Lease Id rather than have one generated for you. This Lease Id can be used to renew or release the lease on the Blob. You can also use it to request a new Lease Id. Without a lease Id, you have to break the lease to get update access to the Blob again.

Lease actions – Acquire

The code below requests a new lease on a Blob. This request will return a string containing a GUID as the Lease Id. If you’d rather, you can create your own Lease Id and pass it in with the request to acquire a lease and it will use your value as the Lease Id. This will only work if there is not currently a lease on the Blob.

After running this code, I get the following results:

If I wait until the lease expires and then display the properties again, I get this:

Calling AcquireLease on a Blob that already has a lease will result in a failure (409 – conflict); however, if you call AcquireLease passing a valid current Lease ID the platform will extend the lease and start the clock on the expiration over. The Lease Id will not change.

Lease actions – Renew

Other than the ability to call AquireLease again there is also an explicit RenewLease method. You must have the current Lease Id of the Blob to do this. You can even renew the lease if it has expired as long as the blob has not been modified or leased again since the lease expired. When you renew a lease, the clock restarts. You can’t change the duration of the lease when you renew it; it will use the duration of the original lease. So if you leased it for a minute originally, it will renew it for a minute and start counting at zero again. If you want to change the duration of the lease, you should use AcquireLease instead.

I stopped the code before calling RenewLease to make sure the lease had expired, and then renewed the lease. Note that I had to pass in the Lease Id with the AccessCondition object.

Lease actions – Change

This changes the Lease Id of the current active lease. You have to provide the current Lease Id and a new Lease Id. An example where you might use this is where the lease ownership needs to be transferred from one component of your system to another. For example, the first component has a lease on a blob, but needs to allow another component to operate on it. The first component could pass the Lease Id to the second component. The second component could change the Lease Id, do what it needs to do, then change it back to the original Lease Id. This allows the second component to temporarily have exclusive access to the blob, prevents the first component from modifying it while it has exclusive access, and then returns access to the first component.

In the code above, leaseID variable is the Lease Id of the current lease. I get a new GUID to change it to, and call to change it.

Lease actions – Release

When you are finished with the blob you can release a lease by either letting it expire, or call the ReleaseLease method to make it immediately available for another client to lease it. This requires the current lease Id.

After running the code above, the first set of output shows that the blob is leased, and for the second, I get this:

So you can see that it successfully released the lease on the Blob.

Lease Actions – Break

What if you don’t know the lease id of an actively leased Blob, but still need to break the lease? The BreakLease method can be used to do this and requires no Lease Id. If you do this, the lease that was active at the time cannot be renewed. When you break a lease, you provide a timespan (“lease break period”). During this time, no lease methods except for Break and Release can be performed on the Blob. When you break the lease on a Blob successfully, the response indicates the interval in seconds until a new lease can be acquired. If one process breaks the lease on a Blob and the original process that had release then makes its own call to release it, another client can immediately acquire a new lease, rather than waiting for the lease break period time to elapse.

The break release time is the amount of time to allow the lease to continue before breaking it.

After running this code, I get this output:

You can see that the state of the Lease is “Broken”.

Container Leases

In addition to putting a lease on a blob you can also put a lease on a container. This gives you exclusive delete access to the container and only controls the ability to delete the container. If you put a lease on a container nobody else will be able to delete that container. Just like with individual blobs, to delete a container that is leased, you must have the lease ID. Most of the commands for leasing a container are the very similar to those used for blobs.

An important thing to note is that while you hold a lease on a container, it has no effect on the ability to update, add, or delete the blobs in that container.

Summary

In this article, I explained what Blob Leases are and how to use them, including code samples for calling the different methods available for managing Blob Leases. In the next article, we’ll look at signed access signatures and stored access policies with container permissions to control access to containers and blobs.