Beispiel #1
0
        public static void AcquireLeaseDuring(this CloudBlob blob, Action <string> action)
        {
            var leaseId = blob.AcquireLease();

            action(leaseId);
            blob.UploadText("text", "text");
            blob.ReleaseLease(leaseId);
        }
Beispiel #2
0
 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);
     }
 }
Beispiel #5
0
        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);
            }
        }
Beispiel #6
0
        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);
        }