예제 #1
0
        public async Task <bool> AcquireAsync(BlobLease lease, string owner)
        {
            CloudBlockBlob leaseBlob = lease.Blob;

            try
            {
                await leaseBlob.FetchAttributesAsync();

                string newLeaseId = Guid.NewGuid().ToString("N");
                if (leaseBlob.Properties.LeaseState == LeaseState.Leased)
                {
                    lease.Token = await leaseBlob.ChangeLeaseAsync(newLeaseId, accessCondition : AccessCondition.GenerateLeaseCondition(lease.Token));
                }
                else
                {
                    lease.Token = await leaseBlob.AcquireLeaseAsync(this.leaseInterval, newLeaseId);
                }

                this.stats.StorageRequests.Increment();
                lease.Owner = owner;
                // Increment Epoch each time lease is acquired or stolen by new host
                lease.Epoch += 1;
                await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(lease), null, AccessCondition.GenerateLeaseCondition(lease.Token), null, null);

                this.stats.StorageRequests.Increment();
            }
            catch (StorageException storageException)
            {
                this.stats.StorageRequests.Increment();
                throw HandleStorageException(lease, storageException);
            }

            return(true);
        }
예제 #2
0
        async Task <bool> AcquireLeaseCoreAsync(AzureBlobLease lease)
        {
            CloudBlockBlob leaseBlob   = lease.Blob;
            bool           retval      = true;
            string         newLeaseId  = Guid.NewGuid().ToString();
            string         partitionId = lease.PartitionId;

            try
            {
                string newToken;
                await leaseBlob.FetchAttributesAsync().ConfigureAwait(false);

                if (leaseBlob.Properties.LeaseState == LeaseState.Leased)
                {
                    if (string.IsNullOrEmpty(lease.Token))
                    {
                        // We reach here in a race condition: when this instance of EventProcessorHost scanned the
                        // lease blobs, this partition was unowned (token is empty) but between then and now, another
                        // instance of EPH has established a lease (getLeaseState() is LEASED). We normally enforce
                        // that we only steal the lease if it is still owned by the instance which owned it when we
                        // scanned, but we can't do that when we don't know who owns it. The safest thing to do is just
                        // fail the acquisition. If that means that one EPH instance gets more partitions than it should,
                        // rebalancing will take care of that quickly enough.
                        return(false);
                    }

                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.HostName, lease.PartitionId, "Need to ChangeLease");
                    newToken = await leaseBlob.ChangeLeaseAsync(newLeaseId, AccessCondition.GenerateLeaseCondition(lease.Token)).ConfigureAwait(false);
                }
                else
                {
                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.HostName, lease.PartitionId, "Need to AcquireLease");

                    try
                    {
                        newToken = await leaseBlob.AcquireLeaseAsync(leaseDuration, newLeaseId).ConfigureAwait(false);
                    }
                    catch (StorageException se)
                        when(se.RequestInformation != null &&
                             se.RequestInformation.ErrorCode.Equals(BlobErrorCodeStrings.LeaseAlreadyPresent, StringComparison.OrdinalIgnoreCase))
                        {
                            // Either some other host grabbed the lease or checkpoint call renewed it.
                            return(false);
                        }
                }

                lease.Token = newToken;
                lease.Owner = this.host.HostName;
                lease.IncrementEpoch(); // Increment epoch each time lease is acquired or stolen by a new host
                await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(lease), null, AccessCondition.GenerateLeaseCondition(lease.Token), null, null).ConfigureAwait(false);
            }
            catch (StorageException se)
            {
                throw HandleStorageException(partitionId, se);
            }

            return(retval);
        }
        async Task <bool> AcquireLeaseCoreAsync(AzureBlobLease lease)
        {
            CloudBlockBlob leaseBlob   = lease.Blob;
            bool           retval      = true;
            string         newLeaseId  = Guid.NewGuid().ToString();
            string         partitionId = lease.PartitionId;

            try
            {
                string newToken;
                await leaseBlob.FetchAttributesAsync().ConfigureAwait(false);

                if (leaseBlob.Properties.LeaseState == LeaseState.Leased)
                {
                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.Id, lease.PartitionId, "Need to ChangeLease");
                    newToken = await leaseBlob.ChangeLeaseAsync(newLeaseId, AccessCondition.GenerateLeaseCondition(lease.Token)).ConfigureAwait(false);
                }
                else
                {
                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.Id, lease.PartitionId, "Need to AcquireLease");
                    newToken = await leaseBlob.AcquireLeaseAsync(leaseDuration, newLeaseId).ConfigureAwait(false);
                }

                lease.Token = newToken;
                lease.Owner = this.host.HostName;
                lease.IncrementEpoch(); // Increment epoch each time lease is acquired or stolen by a new host
                await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(lease), null, AccessCondition.GenerateLeaseCondition(lease.Token), null, null).ConfigureAwait(false);
            }
            catch (StorageException se)
            {
                if (WasLeaseLost(partitionId, se))
                {
                    retval = false;
                }
                else
                {
                    throw;
                }
            }

            return(retval);
        }
        async Task <bool> AcquireLeaseCoreAsync(AzureBlobLease lease)
        {
            CloudBlockBlob leaseBlob   = lease.Blob;
            bool           retval      = true;
            string         newLeaseId  = Guid.NewGuid().ToString();
            string         partitionId = lease.PartitionId;

            try
            {
                bool   renewLease = false;
                string newToken;

                await leaseBlob.FetchAttributesAsync(null, this.defaultRequestOptions, this.operationContext).ConfigureAwait(false);

                if (leaseBlob.Properties.LeaseState == LeaseState.Leased)
                {
                    if (string.IsNullOrEmpty(lease.Token))
                    {
                        // We reach here in a race condition: when this instance of EventProcessorHost scanned the
                        // lease blobs, this partition was unowned (token is empty) but between then and now, another
                        // instance of EPH has established a lease (getLeaseState() is LEASED). We normally enforce
                        // that we only steal the lease if it is still owned by the instance which owned it when we
                        // scanned, but we can't do that when we don't know who owns it. The safest thing to do is just
                        // fail the acquisition. If that means that one EPH instance gets more partitions than it should,
                        // rebalancing will take care of that quickly enough.
                        return(false);
                    }

                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.HostName, lease.PartitionId, "Need to ChangeLease");
                    renewLease = true;
                    newToken   = await leaseBlob.ChangeLeaseAsync(
                        newLeaseId,
                        AccessCondition.GenerateLeaseCondition(lease.Token),
                        this.defaultRequestOptions,
                        this.operationContext).ConfigureAwait(false);
                }
                else
                {
                    ProcessorEventSource.Log.AzureStorageManagerInfo(this.host.HostName, lease.PartitionId, "Need to AcquireLease");
                    newToken = await leaseBlob.AcquireLeaseAsync(
                        leaseDuration,
                        newLeaseId,
                        null,
                        this.defaultRequestOptions,
                        this.operationContext).ConfigureAwait(false);
                }

                lease.Token = newToken;
                lease.Owner = this.host.HostName;
                lease.IncrementEpoch(); // Increment epoch each time lease is acquired or stolen by a new host

                // Renew lease here if needed?
                // ChangeLease doesn't renew so we should avoid lease expiring before next renew interval.
                if (renewLease)
                {
                    await this.RenewLeaseCoreAsync(lease).ConfigureAwait(false);
                }

                // Update owner in the metadata first since clients get ownership information by looking at metadata.
                lease.Blob.Metadata[MetaDataOwnerName] = lease.Owner;
                await lease.Blob.SetMetadataAsync(
                    AccessCondition.GenerateLeaseCondition(lease.Token),
                    this.defaultRequestOptions,
                    this.operationContext).ConfigureAwait(false);

                // Then update deserialized lease content.
                await leaseBlob.UploadTextAsync(
                    JsonConvert.SerializeObject(lease),
                    null,
                    AccessCondition.GenerateLeaseCondition(lease.Token),
                    this.defaultRequestOptions,
                    this.operationContext).ConfigureAwait(false);
            }
            catch (StorageException se)
            {
                throw HandleStorageException(partitionId, se);
            }

            return(retval);
        }
예제 #5
0
        /// <inheritdoc />
        public async Task <bool> AcquireLeaseAsync(Lease lease)
        {
            var azureLease = (AzureBlobLease)lease;

            CloudBlockBlob leaseBlob   = azureLease.Blob;
            bool           retval      = true;
            string         newLeaseId  = Guid.NewGuid().ToString();
            string         partitionId = lease.PartitionId;

            _leaseUpdateCounter.Increment();

            using (_logger.BeginScope("Acquire Lease"))
            {
                _logger.LogInformation("Acquiring lease for partition {partitionId}", lease.PartitionId);

                try
                {
                    bool   renewLease = false;
                    string newToken;

                    using (_storagePerformanceSummary.Time())
                    {
                        await leaseBlob.FetchAttributesAsync(_defaultAccessCondition, _defaultRequestOptions, _operationContext).ConfigureAwait(false);
                    }

                    if (leaseBlob.Properties.LeaseState == LeaseState.Leased)
                    {
                        if (string.IsNullOrEmpty(lease.Token))
                        {
                            return(false);
                        }

                        _logger.LogInformation("Need to ChangeLease: Partition Id: {partitionId}", lease.PartitionId);
                        renewLease = true;

                        using (_storagePerformanceSummary.Time())
                        {
                            newToken = await leaseBlob.ChangeLeaseAsync(newLeaseId, AccessCondition.GenerateLeaseCondition(lease.Token), _defaultRequestOptions, _operationContext).ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        _logger.LogInformation("Need to AcquireLease: Partition Id: {partitionId}", lease.PartitionId);

                        using (_storagePerformanceSummary.Time())
                        {
                            newToken = await leaseBlob.AcquireLeaseAsync(LeaseDuration, newLeaseId, _defaultAccessCondition, _defaultRequestOptions, _operationContext).ConfigureAwait(false);
                        }
                    }

                    lease.Token = newToken;
                    lease.Owner = _eventProcessorHostName;
                    lease.IncrementEpoch(); // Increment epoch each time lease is acquired or stolen by a new host

                    if (renewLease)
                    {
                        await RenewLeaseCoreAsync(azureLease).ConfigureAwait(false);
                    }
                    leaseBlob.Metadata[MetaDataOwnerName] = lease.Owner;

                    using (_storagePerformanceSummary.Time())
                    {
                        await leaseBlob.SetMetadataAsync(AccessCondition.GenerateLeaseCondition(lease.Token), _defaultRequestOptions, _operationContext).ConfigureAwait(false);
                    }

                    using (_storagePerformanceSummary.Time())
                    {
                        await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(lease), _leaseEncoding, AccessCondition.GenerateLeaseCondition(lease.Token), _defaultRequestOptions, _operationContext).ConfigureAwait(false);
                    }
                }
                catch (StorageException e)
                {
                    _leaseErrorCounter.Increment();
                    var se = AzureBlobCommon.CheckForLeaseLostException(partitionId, e, _logger);

                    _logger.LogError(se, "Error acquiring lease for partition {partitionId}", lease.PartitionId);
                    throw se;
                }
            }

            return(retval);
        }