Many software solutions require mutual exclusion to ensure that no two concurrent processes are in a critical section of code at a time. Software that is running in a single application domain can easily meet this requirement by utilizing thread concurrency mechanisms.
Below is a simple example of how this is handled in an application consisting of a single running process.
This is a simple, yet effective solution that works as prescribed for single node applications. Things get a little bit more complicated when you are developing solutions in the cloud or any other multi-node system.
How can we transform the above code to ensure mutual exclusion when there are multiple processes running?
Luckily, we can achieve this same behavior by utilizing the Lease operation on blobs in Azure Storage. A lease on a blob can effectively lock the blob for a specified duration (15-60 seconds). When the lease duration expires, the lease is released and is made available for any other process. To avoid having the lease expire, a Renew operation is made available to extend the lease by the same duration. If a process no longer requires the lease, it can make a call to Release to make the lease available to other callers. Any process that attempts to acquire a lease (or perform other operations) on a leased blob will result in a 409 Conflict exception. More information can be found here.
Lease management is often not a trivial task. For that reason, we have implemented a helper class that handles some of the intricacies when dealing with blob lease management. The code can be found here.
With the CloudLock helper class, we can transform the above code snippet to an equivalent multi process solution.
By default, the CloudLock class sets the duration of the lease acquisition to 30 seconds. Once a lease is acquired, a background task automatically renews the lease at the halfway point of the duration of the lease acquisition. Note that these values are defaults and may be configured.
The following diagram can help you visualize the process: