public static void AcquireLeaseDuring(this CloudBlob blob, Action <string> action) { var leaseId = blob.AcquireLease(); action(leaseId); blob.UploadText("text", "text"); blob.ReleaseLease(leaseId); }
public static string TryAcquireLease(this CloudBlob blob) { try { return(blob.AcquireLease()); } catch (WebException e) { if ((e.Response == null) || ((HttpWebResponse)e.Response).StatusCode != HttpStatusCode.Conflict) // 409, already leased { throw; } e.Response.Close(); return(null); } }
/// <summary> /// Try to acquire a lease on the blob. If the acquire is successful the lease will be renewed at every 60 seconds. /// In order to stop the renew task the <see cref="Stats.AzureCdnLogs.Common.AzureBlobLeaseManager.TryReleaseLease(CloudBlob)"/> needs to be invoked /// or the token to be cancelled. /// </summary> /// <param name="blob">The blob to acquire the lease on.</param> /// <param name="token">A token to cancel the operation.</param> /// <param name="renewStatusTask">The renew task.</param> /// <returns>True if the lease was acquired. </returns> public bool AcquireLease(CloudBlob blob, CancellationToken token, out Task <bool> renewStatusTask) { renewStatusTask = null; blob.FetchAttributes(); if (token.IsCancellationRequested || blob.Properties.LeaseStatus == LeaseStatus.Locked) { return(false); } var proposedLeaseId = Guid.NewGuid().ToString(); string leaseId; leaseId = blob.AcquireLease(TimeSpan.FromSeconds(MaxRenewPeriodInSeconds), proposedLeaseId); _leasedBlobs.AddOrUpdate(blob.Uri, leaseId, (uri, guid) => leaseId); //start a task that will renew the lease until the token is cancelled or the Release methods was invoked renewStatusTask = Task.Run(() => { if (!token.IsCancellationRequested) { //if the token was cancelled just try to release the lease as soon as possible using (token.Register(() => { TryReleaseLease(blob); })) { while (!token.IsCancellationRequested) { string blobLeaseId = string.Empty; //it will renew the lease only if the lease was not explicitelly released if (_leasedBlobs.TryGetValue(blob.Uri, out blobLeaseId) && blobLeaseId == leaseId) { int sleepBeforeRenewInSeconds = MaxRenewPeriodInSeconds - 5 < 0 ? MaxRenewPeriodInSeconds : MaxRenewPeriodInSeconds - 5; Thread.Sleep(sleepBeforeRenewInSeconds * 1000); AccessCondition acc = new AccessCondition() { LeaseId = leaseId }; blob.RenewLease(accessCondition: acc, options: _blobRequestOptions, operationContext: null); } else { break; } } } } token.ThrowIfCancellationRequested(); return(false); }, token); return(true); }
public static string TryAcquireLease(this CloudBlob blob, int leaseLengthSeconds) { try { return(blob.AcquireLease(leaseLengthSeconds)); } catch (WebException ex) { if (ex.Response == null || ((HttpWebResponse)ex.Response).StatusCode != HttpStatusCode.Conflict) { throw; } ex.Response.Close(); return(null); } }
public void SnapshotLeaseBlobWithWrongLeaseID() { string containerName = Utility.GenNameString("container"); string blobName = Utility.GenNameString("blob"); CloudBlobContainer container = blobUtil.CreateContainer(containerName); try { CloudBlob blob = blobUtil.CreateRandomBlob(container, blobName); blob.AcquireLease(TimeSpan.FromMinutes(1), string.Empty); string wrongLeaseId = Guid.NewGuid().ToString(); Test.Assert(!CommandAgent.SnapshotAzureStorageBlob(containerName, blobName, wrongLeaseId), Utility.GenComparisonData("Snapshot-AzureStorageBlob", false)); CommandAgent.ValidateErrorMessage(MethodBase.GetCurrentMethod().Name); } finally { blobUtil.RemoveContainer(containerName); } }
public void SnapshotLeasedBlob() { string containerName = Utility.GenNameString("container"); string blobName = Utility.GenNameString("blob"); CloudBlobContainer container = blobUtil.CreateContainer(containerName); try { CloudBlob blob = blobUtil.CreateRandomBlob(container, blobName); string leaseId = blob.AcquireLease(TimeSpan.FromMinutes(1), string.Empty); Test.Assert(CommandAgent.SnapshotAzureStorageBlob(containerName, blobName, leaseId), Utility.GenComparisonData("Snapshot-AzureStorageBlob", true)); if (lang == Language.NodeJS) { try { string url = (CommandAgent as NodeJSAgent).Output[0]["url"] as string; DateTimeOffset snapshot = new DateTimeOffset((DateTime)(CommandAgent as NodeJSAgent).Output[0]["snapshot"]); CloudBlob snapshotBlob = blobUtil.GetBlobReference(container, blobName, blob.BlobType, snapshot); Test.Assert(snapshotBlob.IsSnapshot, "Expect the the instance is a snapshot"); Test.Assert(snapshotBlob.SnapshotQualifiedUri.ToString() == url, string.Format("Expect the URL to be {0} while get {1}", snapshotBlob.SnapshotQualifiedUri.AbsolutePath, url)); } catch (Exception e) { Test.Error(string.Format("{0} error: {1}", MethodBase.GetCurrentMethod().Name, e.Message)); } } } finally { blobUtil.RemoveContainer(containerName); } }
/// <summary> /// Try to acquire a lease on the blob. If the acquire is successful the lease will be renewed at every 60 seconds. /// In order to stop the renew task the <see cref="Stats.AzureCdnLogs.Common.AzureBlobLeaseManager.TryReleaseLease(CloudBlob)"/> needs to be invoked /// or the token to be cancelled. /// </summary> /// <param name="blob">The blob to acquire the lease on.</param> /// <param name="token">A token to cancel the operation.</param> /// <param name="renewStatusTask">The renew task.</param> /// <returns>True if the lease was acquired. </returns> public AzureBlobLockResult AcquireLease(CloudBlob blob, CancellationToken token) { blob.FetchAttributes(); if (token.IsCancellationRequested || blob.Properties.LeaseStatus == LeaseStatus.Locked) { _logger.LogInformation("AcquireLease: The operation was cancelled or the blob lease is already taken. Blob {BlobUri}, Cancellation status {IsCancellationRequested}, BlobLeaseStatus {BlobLeaseStatus}.", blob.Uri.AbsoluteUri, token.IsCancellationRequested, blob.Properties.LeaseStatus); return(AzureBlobLockResult.FailedLockResult(blob)); } var proposedLeaseId = Guid.NewGuid().ToString(); var leaseId = blob.AcquireLease(TimeSpan.FromSeconds(MaxRenewPeriodInSeconds), proposedLeaseId); var lockResult = new AzureBlobLockResult(blob: blob, lockIsTaken: true, leaseId: leaseId, linkToken: token); //start a task that will renew the lease until the token is cancelled or the Release methods was invoked var renewStatusTask = new Task((lockresult) => { var blobLockResult = (AzureBlobLockResult)lockresult; _logger.LogInformation("RenewLeaseTask: Started for BlobUri {BlobUri}. ThreadId {ThreadId}. IsCancellationRequested {IsCancellationRequested}. LeaseId {LeaseId}", blob.Uri.AbsoluteUri, Thread.CurrentThread.ManagedThreadId, blobLockResult.BlobOperationToken.IsCancellationRequested, blobLockResult.LeaseId); int sleepBeforeRenewInSeconds = MaxRenewPeriodInSeconds - OverlapRenewPeriodInSeconds < 0 ? MaxRenewPeriodInSeconds : MaxRenewPeriodInSeconds - OverlapRenewPeriodInSeconds; if (!blobLockResult.BlobOperationToken.IsCancellationRequested) { while (!blobLockResult.BlobOperationToken.Token.IsCancellationRequested) { Thread.Sleep(sleepBeforeRenewInSeconds * 1000); //it will renew the lease only if the lease was not explicitly released try { if (!blobLockResult.Blob.Exists()) { blobLockResult.BlobOperationToken.Cancel(); break; } AccessCondition acc = new AccessCondition { LeaseId = blobLockResult.LeaseId }; blob.RenewLease(accessCondition: acc, options: _blobRequestOptions, operationContext: null); _logger.LogInformation("RenewLeaseTask: Lease was renewed for BlobUri {BlobUri} and LeaseId {LeaseId}.", blob.Uri.AbsoluteUri, blobLockResult.LeaseId); } catch (StorageException exception) { _logger.LogWarning(LogEvents.FailedBlobLease, exception, "RenewLeaseTask: The Lease could not be renewed for BlobUri {BlobUri}. ExpectedLeaseId {LeaseId}. CurrentLeaseId {CurrentLeaseId}.", blob.Uri.AbsoluteUri, leaseId, blobLockResult.LeaseId); blobLockResult.BlobOperationToken.Cancel(); break; } } } }, lockResult, TaskCreationOptions.LongRunning); renewStatusTask.Start(); return(lockResult); }