Wrapper around a Windows Azure Blob Lease
Esempio n. 1
0
        private async Task RunTaskWhenBlobLeaseAcquired(BlobLeaseManager leaseManager, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                // Try to acquire the blob lease, otherwise wait for some time before we can try again.
                string leaseId = await this.TryAcquireLeaseOrWait(leaseManager, token);

                if (!string.IsNullOrEmpty(leaseId))
                {
                    // Create a new linked cancellation token source, so if either the
                    // original token is canceled or the lease cannot be renewed,
                    // then the leader task can be canceled.
                    using (var leaseCts =
                               CancellationTokenSource.CreateLinkedTokenSource(new[] { token }))
                    {
                        // Run the leader task.
                        var leaderTask = this.taskToRunWhenLeaseAcquired.Invoke(leaseCts.Token);

                        // Keeps renewing the lease in regular intervals.
                        // If the lease cannot be renewed, then the task completes.
                        var renewLeaseTask =
                            this.KeepRenewingLease(leaseManager, leaseId, leaseCts.Token);

                        // When any task completes (either the leader task or when it could
                        // not renew the lease) then cancel the other task.
                        await CancelAllWhenAnyCompletes(leaderTask, renewLeaseTask, leaseCts);
                    }
                }
            }
        }
        private async Task RunTaskWhenBlobLeaseAcquired(BlobLeaseManager leaseManager, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                // Try to acquire the blob lease, otherwise wait for some time before we can try again.
                string leaseId = await this.TryAcquireLeaseOrWait(leaseManager, token);

                if (!string.IsNullOrEmpty(leaseId))
                {
                    // Create a new linked cancellation token source, so if either the 
                    // original token is canceled or the lease cannot be renewed,
                    // then the leader task can be canceled.
                    using (var leaseCts = 
                        CancellationTokenSource.CreateLinkedTokenSource(new[] { token }))
                    {
                        // Run the leader task.
                        var leaderTask = this.taskToRunWhenLeaseAcquired.Invoke(leaseCts.Token);

                        // Keeps renewing the lease in regular intervals. 
                        // If the lease cannot be renewed, then the task completes.
                        var renewLeaseTask = 
                            this.KeepRenewingLease(leaseManager, leaseId, leaseCts.Token);

                        // When any task completes (either the leader task or when it could
                        // not renew the lease) then cancel the other task.
                        await CancelAllWhenAnyCompletes(leaderTask, renewLeaseTask, leaseCts);
                    }
                }
            }
        }
Esempio n. 3
0
        private async Task <string> TryAcquireLeaseOrWait(BlobLeaseManager leaseManager, CancellationToken token)
        {
            try
            {
                var leaseId = await leaseManager.AcquireLeaseAsync(token);

                if (!string.IsNullOrEmpty(leaseId))
                {
                    return(leaseId);
                }

                await Task.Delay(AcquireAttemptInterval, token);

                return(null);
            }
            catch (OperationCanceledException)
            {
                return(null);
            }
        }
Esempio n. 4
0
        private async Task KeepRenewingLease(BlobLeaseManager leaseManager, string leaseId, CancellationToken token)
        {
            var renewOffset = new Stopwatch();

            while (!token.IsCancellationRequested)
            {
                try
                {
                    // Immediately attempt to renew the lease
                    // We cannot be sure how much time has passed since the lease was actually acquired
                    renewOffset.Restart();
                    var renewed = await leaseManager.RenewLeaseAsync(leaseId, token);

                    renewOffset.Stop();

                    if (!renewed)
                    {
                        return;
                    }

                    // We delay based on the time from the start of the last renew request to ensure
                    var renewIntervalAdjusted = RenewInterval - renewOffset.Elapsed;

                    // If the adjusted interval is greater than zero wait for that long
                    if (renewIntervalAdjusted > TimeSpan.Zero)
                    {
                        await Task.Delay(RenewInterval - renewOffset.Elapsed, token);
                    }
                }
                catch (OperationCanceledException)
                {
                    leaseManager.ReleaseLease(leaseId);

                    return;
                }
            }
        }
        private async Task<string> TryAcquireLeaseOrWait(BlobLeaseManager leaseManager, CancellationToken token)
        {
            try
            {
                var leaseId = await leaseManager.AcquireLeaseAsync(token);
                if (!string.IsNullOrEmpty(leaseId))
                {
                    return leaseId;
                }

                await Task.Delay(AcquireAttemptInterval, token);
                return null;
            }
            catch (OperationCanceledException)
            {
                return null;
            }
        }
        public async Task RunTaskWhenMutexAcquired(CancellationToken token)
        {
            var leaseManager = new BlobLeaseManager(this.blobSettings);

            await this.RunTaskWhenBlobLeaseAcquired(leaseManager, token);
        }
        private async Task KeepRenewingLease(BlobLeaseManager leaseManager, string leaseId, CancellationToken token)
        {
            var renewOffset = new Stopwatch();

            while (!token.IsCancellationRequested)
            {
                try
                {
                    // Immediately attempt to renew the lease
                    // We cannot be sure how much time has passed since the lease was actually acquired
                    renewOffset.Restart();
                    var renewed = await leaseManager.RenewLeaseAsync(leaseId, token);
                    renewOffset.Stop();

                    if (!renewed)
                    {
                        return;
                    }

                    // We delay based on the time from the start of the last renew request to ensure
                    var renewIntervalAdjusted = RenewInterval - renewOffset.Elapsed;
                    
                    // If the adjusted interval is greater than zero wait for that long
                    if (renewIntervalAdjusted > TimeSpan.Zero)
                    {
                        await Task.Delay(RenewInterval - renewOffset.Elapsed, token);
                    }
                }
                catch (OperationCanceledException)
                {
                    leaseManager.ReleaseLease(leaseId);

                    return;
                }
            }
        }
Esempio n. 8
0
        public async Task RunTaskWhenMutexAcquired(CancellationToken token)
        {
            var leaseManager = new BlobLeaseManager(this.blobSettings);

            await this.RunTaskWhenBlobLeaseAcquired(leaseManager, token);
        }