Created
August 22, 2017 19:52
-
-
Save veyodev/8987ce1e98914b00342ac29387fc0f85 to your computer and use it in GitHub Desktop.
This file contains 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 DistributedMutex { | |
private readonly string key; | |
private readonly string storageConnectionString; | |
private readonly string storageContainerName; | |
private CloudBlobClient blobClient; | |
private string leaseId; | |
public DistributedMutex(string storageConnectionString, string storageContainerName, string key) | |
{ | |
this.key = key; | |
this.storageConnectionString = storageConnectionString; | |
this.storageContainerName = storageContainerName; | |
} | |
/// <summary> | |
/// Acquires a lease blob. | |
/// </summary> | |
public async Task AcquireAsync() | |
{ | |
var storageAccount = CloudStorageAccount.Parse(storageConnectionString); | |
blobClient = storageAccount.CreateCloudBlobClient(); | |
var containerReference = blobClient.GetContainerReference(storageContainerName); | |
await containerReference.CreateIfNotExistsAsync(); | |
var blobReference = containerReference.GetBlockBlobReference(key); | |
if (!await blobReference.ExistsAsync()) await blobReference.UploadTextAsync(string.Empty); | |
try { | |
leaseId = await blobReference.AcquireLeaseAsync(TimeSpan.FromSeconds(60)); | |
} | |
catch (StorageException ex) { | |
Console.WriteLine("Error while acquiring an a job lease."); | |
Console.WriteLine(ex.Message); | |
if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) throw new InvalidOperationException($"Another job is already running for {key}."); | |
throw; | |
} | |
} | |
/// <summary> | |
/// Releases a lease blob. | |
/// </summary> | |
public async Task ReleaseLockAsync() | |
{ | |
var containerReference = blobClient.GetContainerReference(storageContainerName); | |
await containerReference.CreateIfNotExistsAsync(); | |
var blobReference = containerReference.GetBlockBlobReference(key); | |
await blobReference.ReleaseLeaseAsync(new AccessCondition { | |
LeaseId = leaseId | |
}); | |
} | |
/// <summary> | |
/// Renews the lease. | |
/// </summary> | |
public async Task RenewAsync() | |
{ | |
var containerClientReference = blobClient.GetContainerReference(storageContainerName); | |
await containerClientReference.CreateIfNotExistsAsync(); | |
var blobReference = containerClientReference.GetBlockBlobReference(key); | |
await blobReference.RenewLeaseAsync(new AccessCondition { | |
LeaseId = leaseId | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment