diff --git a/src/DistributedLock.Azure/AzureBlobLeaseDistributedLock.cs b/src/DistributedLock.Azure/AzureBlobLeaseDistributedLock.cs index 32a67f8e..0e11f44a 100644 --- a/src/DistributedLock.Azure/AzureBlobLeaseDistributedLock.cs +++ b/src/DistributedLock.Azure/AzureBlobLeaseDistributedLock.cs @@ -105,11 +105,11 @@ static string ConvertToValidName(string name) ); private async ValueTask TryAcquireAsync( - BlobLeaseClientWrapper leaseClient, + BlobLeaseClientWrapper leaseClient, CancellationToken cancellationToken, bool isRetryAfterCreate) { - try { await leaseClient.AcquireAsync(this._options.duration, cancellationToken).ConfigureAwait(false); } + try { await leaseClient.AcquireAsync(this._options.duration, cancellationToken).ConfigureAwait(false); } catch (RequestFailedException acquireException) { if (acquireException.ErrorCode == AzureErrors.LeaseAlreadyPresent) { return null; } @@ -135,6 +135,11 @@ static string ConvertToValidName(string name) { // if the retry fails and we created, attempt deletion to clean things up try { await this._blobClient.DeleteIfExistsAsync().ConfigureAwait(false); } + catch (RequestFailedException deletionException) when (deletionException.ErrorCode == AzureErrors.LeaseIdMissing) + { + // handle the race condition where we try to delete and someone else acquired it + // only the original Exception from TryAcquireAsync should be thrown + } catch (Exception deletionException) { throw new AggregateException(retryException, deletionException); @@ -160,7 +165,7 @@ internal sealed class InternalHandle : IDistributedSynchronizationHandle, LeaseM private readonly bool _ownsBlob; private readonly AzureBlobLeaseDistributedLock _lock; private readonly LeaseMonitor _leaseMonitor; - + public InternalHandle(BlobLeaseClientWrapper leaseClient, bool ownsBlob, AzureBlobLeaseDistributedLock @lock) { this._leaseClient = leaseClient; @@ -193,7 +198,7 @@ public async ValueTask DisposeAsync() { await this._lock._blobClient.DeleteIfExistsAsync(leaseId: this._leaseClient.LeaseId).ConfigureAwait(false); } - else + else { await this._leaseClient.ReleaseAsync().ConfigureAwait(false); }