public static async Task <string> AcquireLeaseAsync(this CloudBlob blob, TimeSpan?leaseTime = null, CancellationToken cancellationToken = default(CancellationToken)) { // From: https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx // The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. // The lock duration can be 15 to 60 seconds, or can be infinite. if (leaseTime.HasValue && (leaseTime.Value <TimeSpan.FromSeconds(15) | leaseTime.Value> TimeSpan.FromSeconds(60))) { throw new ArgumentOutOfRangeException(nameof(leaseTime), string.Format("{0} must be between 15 and 60 seconds", nameof(leaseTime))); } var defaultLeaseTime = TimeSpan.FromSeconds(15); var proposedLeaseId = (string)null; // Proposed lease id (leave it null for storage service to return you one). var blobDoesNotExist = false; var leaseId = (string)null; leaseTime = leaseTime.HasValue ? leaseTime : defaultLeaseTime; try { // Optimistically try to acquire the lease. The blob may not yet // exist. If it doesn't we handle the 404, create it, and retry below leaseId = await blob.AcquireLeaseAsync(leaseTime, proposedLeaseId, null, null, null, cancellationToken).ConfigureAwait(false); } catch (StorageException exception) { if (exception.RequestInformation != null) { if (exception.RequestInformation.HttpStatusCode == 404) { blobDoesNotExist = true; } else { throw; } } else { throw; } } if (blobDoesNotExist) { await blob.UploadTextAsync(string.Empty, null, cancellationToken); leaseId = await blob.AcquireLeaseAsync(leaseTime, proposedLeaseId, null, null, null, cancellationToken).ConfigureAwait(false); } return(leaseId); }
private static void DoLeaseOperation(CloudBlob blob, string leaseId, LeaseAction action) { switch (action) { case LeaseAction.Acquire: blob.AcquireLeaseAsync(TimeSpan.FromSeconds(90), leaseId).Wait(); break; case LeaseAction.Renew: blob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); break; case LeaseAction.Release: blob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); break; case LeaseAction.Break: blob.BreakLeaseAsync(TimeSpan.FromSeconds(90)).Wait(); break; case LeaseAction.Change: blob.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); break; default: throw new ArgumentOutOfRangeException(nameof(action), action, null); } }
public static async Task <string> TryAcquireLeaseAsync(this CloudBlob blob, TimeSpan?leaseTime = null, int maxLeaseAttempts = 1, CancellationToken cancellationToken = default(CancellationToken)) { if (blob == null) { throw new ArgumentNullException(nameof(blob)); } if (maxLeaseAttempts < 1 || maxLeaseAttempts > 10) { throw new ArgumentOutOfRangeException(string.Format("{0} must be between 1 and 10", nameof(maxLeaseAttempts))); } var leaseId = (string)null; for (var attempts = 0; attempts < maxLeaseAttempts; attempts++) { try { leaseId = await blob.AcquireLeaseAsync(leaseTime, cancellationToken).ConfigureAwait(false); if (!string.IsNullOrEmpty(leaseId)) { break; } } catch (StorageException e) { // If the status code is 409 (HttpStatusCode.Conflict), it means the resource is already leased if (e.RequestInformation?.HttpStatusCode == 409) { if (attempts < maxLeaseAttempts - 1) { await Task.Delay(500).ConfigureAwait(false); // Make sure we don't retry too quickly } } else { throw; } } } return(leaseId); }
public static string AcquireLease(this CloudBlob blob, TimeSpan?leaseTime, string proposedLeaseId, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) { return(blob.AcquireLeaseAsync(leaseTime, proposedLeaseId, accessCondition, options, operationContext).GetAwaiter().GetResult()); }