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); }
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); }
/// <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); }