Esempio n. 1
0
        /// <inheritdoc/>
        public Lease FromLeaseToken(string leaseToken)
        {
            if (leaseToken is null)
            {
                throw new ArgumentNullException(nameof(leaseToken));
            }

            return(AzureLease.FromToken(this, leaseToken));
        }
Esempio n. 2
0
        /// <inheritdoc/>
        public async Task <Lease> AcquireAsync(LeasePolicy leasePolicy, string?proposedLeaseId = null)
        {
            if (leasePolicy is null)
            {
                throw new ArgumentNullException(nameof(leasePolicy));
            }

            this.logger.LogDebug($"Acquiring lease for '{leasePolicy.ActorName}' with name '{leasePolicy.Name}', duration '{leasePolicy.Duration}', and proposed id '{proposedLeaseId}'");

            try
            {
                await this.InitialiseAsync().ConfigureAwait(false);

                // Once Initialise has been called, we know this.container is set.
                CloudBlockBlob blob = this.container !.GetBlockBlobReference((leasePolicy.Name ?? Guid.NewGuid().ToString()).ToLowerInvariant());

                await Retriable.RetryAsync(
                    async() =>
                {
                    try
                    {
                        if (!await blob.ExistsAsync().ConfigureAwait(false))
                        {
                            using var ms = new MemoryStream();
                            await blob.UploadFromStreamAsync(ms).ConfigureAwait(false);
                        }
                    }
                    catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == 400)
                    {
                        // Turn that into an invalid operation exception for standard "bad request" semantics (bad name)
                        throw new InvalidOperationException();
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        // Turn that into an invalid operation exception for standard "bad request" semantics (bad duration)
                        throw new InvalidOperationException();
                    }
                },
                    CancellationToken.None,
                    new Count(10),
                    new AggregatePolicy { Policies = { new DoNotRetryOnInvalidOperationPolicy(), new DoNotRetryOnConflictPolicy(), new DoNotRetryOnInitializationFailurePolicy() } }).ConfigureAwait(false);

                string id = await Retriable.RetryAsync(
                    async() =>
                {
                    try
                    {
                        return(await blob.AcquireLeaseAsync(leasePolicy.Duration, proposedLeaseId));
                    }
                    catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == 400)
                    {
                        // Turn that into an invalid operation exception for standard "bad request" semantics (bad name)
                        throw new InvalidOperationException();
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        // Turn that into an invalid operation exception for standard "bad request" semantics (bad duration)
                        throw new InvalidOperationException();
                    }
                },
                    CancellationToken.None,
                    new Count(10),
                    new AggregatePolicy { Policies = { new DoNotRetryOnInvalidOperationPolicy(), new DoNotRetryOnConflictPolicy(), new DoNotRetryOnInitializationFailurePolicy() } }).ConfigureAwait(false);

                var lease = new AzureLease(this, leasePolicy, id);
                lease.SetLastAcquired(DateTimeOffset.Now);

                this.logger.LogDebug($"Acquired lease for '{leasePolicy.ActorName}' with name '{leasePolicy.Name}', duration '{leasePolicy.Duration}', and actual id '{id}'");

                return(lease);
            }
            catch (StorageException exception)
            {
                if (exception.RequestInformation.HttpStatusCode == 409)
                {
                    this.logger.LogError($"Failed to acquire lease for '{leasePolicy.ActorName}'. The lease was held by another party. The lease name was '{leasePolicy.Name}', duration '{leasePolicy.Duration}', and proposed id '{proposedLeaseId}'");
                    throw new LeaseAcquisitionUnsuccessfulException(leasePolicy, exception);
                }
                else
                {
                    this.logger.LogError($"Failed to acquire lease for '{leasePolicy.ActorName}' due to storage failure. The lease name was '{leasePolicy.Name}', duration '{leasePolicy.Duration}', and proposed id '{proposedLeaseId}'");
                    throw;
                }
            }
            catch (InitializationFailureException)
            {
                this.logger.LogError($"Failed to acquire lease for '{leasePolicy.ActorName}' due to storage intiialization failure. The lease name was '{leasePolicy.Name}', duration '{leasePolicy.Duration}', and proposed id '{proposedLeaseId}'");
                throw;
            }
        }