Created
November 21, 2018 08:23
-
-
Save mjul/15827ed7ec7a27aa184fa8b5e87a657b to your computer and use it in GitHub Desktop.
Azure StorageAccount ClobBlob leases - useful as semaphores for ensuring e.g. only on job is processing a given queue at a time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class AzureStorageCloudBlobLease | |
{ | |
private readonly CloudBlob blob; | |
private string leaseId; | |
public AzureStorageCloudBlobLease(CloudBlob blob) | |
{ | |
this.blob = blob ?? throw new ArgumentNullException(nameof(blob)); | |
} | |
public async Task AcquireAsync(TimeSpan leaseTime, TimeSpan maxWaitingTimeForLease) | |
{ | |
var startTime = DateTime.UtcNow; | |
while (true) | |
{ | |
var timedOut = DateTime.UtcNow > startTime.Add(maxWaitingTimeForLease); | |
try | |
{ | |
leaseId = await blob.AcquireLeaseAsync(leaseTime, Guid.NewGuid().ToString()); | |
break; | |
} | |
catch (StorageException sex) when (sex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) | |
{ | |
if (!timedOut) | |
{ | |
// Randomize the waking up times a bit for heijunka (平準化) (load-levelling) | |
Thread.Sleep(TimeSpan.FromMilliseconds(750 + new System.Random().Next(500))); | |
} | |
else | |
{ | |
throw new ApplicationException("Could not acquire lease", sex); | |
} | |
} | |
} | |
} | |
public async Task RenewAsync() | |
{ | |
AssertLeaseAcquired(); | |
await blob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(this.leaseId)); | |
} | |
private void AssertLeaseAcquired() | |
{ | |
if (leaseId is null) throw new InvalidOperationException("Lease not acquired"); | |
} | |
public async Task ReleaseAsync() | |
{ | |
if (leaseId is null) throw new InvalidOperationException("Lease not acquired"); | |
await this.blob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(this.leaseId)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment