/// <summary> /// Renews the lease /// </summary> /// <param name="lease">The lease to renew</param> /// <returns>True if the lease is renewed successfully</returns> private async Task <bool> RenewLeaseCoreAsync(AzureBlobLease lease) { CloudBlockBlob leaseBlob = lease.Blob; string partitionId = lease.PartitionId; using (_logger.BeginScope("Renew Lease Core")) { try { _logger.LogDebug("Core renewal for partition {partitionId}", lease.PartitionId); using (_storagePerformanceSummary.Time()) { await leaseBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(lease.Token), _defaultRequestOptions, _operationContext).ConfigureAwait(false); } _logger.LogDebug("Core renewal completed for partition {partitionId}", lease.PartitionId); } catch (StorageException e) { var se = AzureBlobCommon.CheckForLeaseLostException(partitionId, e, _logger); _logger.LogError(se, "Renewing lease failed for partition {partitionId}", lease.PartitionId); throw se; } } return(true); }
/// <inheritdoc /> public async Task <bool> ReleaseLeaseAsync(Lease lease) { using (_logger.BeginScope("Renew Lease")) { _logger.LogInformation("Releasing lease: Partition Id: {partitionId}", lease.PartitionId); AzureBlobLease azureLease = lease as AzureBlobLease; CloudBlockBlob leaseBlob = azureLease.Blob; string partitionId = azureLease.PartitionId; try { string leaseId = lease.Token; AzureBlobLease releasedCopy = new AzureBlobLease(azureLease, leaseBlob) { Token = string.Empty, Owner = string.Empty }; leaseBlob.Metadata.Remove(MetaDataOwnerName); _logger.LogDebug("Setting metadata for partition {partitionId}", partitionId); using (_storagePerformanceSummary.Time()) { await leaseBlob.SetMetadataAsync(AccessCondition.GenerateLeaseCondition(leaseId), _defaultRequestOptions, _operationContext).ConfigureAwait(false); } _logger.LogDebug("Uploading lease data for partition {partitionId}", partitionId); using (_storagePerformanceSummary.Time()) { await leaseBlob.UploadTextAsync(JsonConvert.SerializeObject(releasedCopy), _leaseEncoding, AccessCondition.GenerateLeaseCondition(leaseId), _defaultRequestOptions, _operationContext).ConfigureAwait(false); } _logger.LogDebug("Release the lease for for partition {partitionId}", partitionId); using (_storagePerformanceSummary.Time()) { await leaseBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), _defaultRequestOptions, _operationContext).ConfigureAwait(false); } } catch (StorageException e) { var se = AzureBlobCommon.CheckForLeaseLostException(partitionId, e, _logger); _logger.LogError(se, "Error releasing lease for partition {partitionId}", lease.PartitionId); throw se; } } return(true); }
/// <summary> /// Updates the lease /// </summary> /// <param name="lease">The lease to update</param> /// <returns>True if updated successfully</returns> private async Task <bool> UpdateLeaseCoreAsync(AzureBlobLease lease) { var success = false; if (lease != null && !string.IsNullOrEmpty(lease.Token)) { } else { success = true; _logger.LogInformation("Updating lease: Partition Id: {partitionId}", lease.PartitionId); string partitionId = lease.PartitionId; string token = lease.Token; CloudBlockBlob leaseBlob = lease.Blob; try { string jsonToUpload = JsonConvert.SerializeObject(lease); _logger.LogInformation("Updating lease: Partition Id: {partitionId}, RawJson: {json}", lease.PartitionId, jsonToUpload); using (_storagePerformanceSummary.Time()) { await leaseBlob.UploadTextAsync(jsonToUpload, _leaseEncoding, AccessCondition.GenerateLeaseCondition(token), _defaultRequestOptions, _operationContext).ConfigureAwait(false); } _logger.LogDebug("Updated lease: Partition Id: {partitionId}", lease.PartitionId); } catch (StorageException e) { var se = AzureBlobCommon.CheckForLeaseLostException(partitionId, e, _logger); _logger.LogError(se, "Updating lease for partition {partitionId}", lease.PartitionId); throw se; } } return(success); }
/// <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); }