public async Task<bool> TryLock() { try { _lease = _blobLeaseFactory.CreateLease(_blob); _leaseId = await _lease.TryAcquireLease(); if (_leaseId == null) { DisposeLease(); return false; } await _blob.FetchAttributesAsync(); if (_blob.Metadata.ContainsKey(UpdateDomainInstancesKey)) { string[] instanceIds = _blob.Metadata[UpdateDomainInstancesKey].Split(','); _instanceIds = new HashSet<string>(instanceIds); } _updateDomain = _blob.Metadata.ContainsKey(UpdateDomainKey) ? _blob.Metadata[UpdateDomainKey] : string.Empty; return true; } catch (Exception e) { if (e is StorageException || e is WebException) { DisposeLease(); Trace.TraceInformation($"Failed to acquire the lease on blob {_blob.Name}", e); return false; } throw; } }
public async Task <bool> TryLock() { try { _lease = _blobLeaseFactory.CreateLease(_blob); _leaseId = await _lease.TryAcquireLease(); if (_leaseId == null) { DisposeLease(); return(false); } await _blob.FetchAttributesAsync(); if (_blob.Metadata.ContainsKey(UpdateDomainInstancesKey)) { string[] instanceIds = _blob.Metadata[UpdateDomainInstancesKey].Split(','); _instanceIds = new HashSet <string>(instanceIds); } _updateDomain = _blob.Metadata.ContainsKey(UpdateDomainKey) ? _blob.Metadata[UpdateDomainKey] : string.Empty; return(true); } catch (StorageException e) { DisposeLease(); Trace.TraceInformation($"Failed to acquire the lease on blob {_blob.Name}", e); return(false); } }
private async Task TestThatLockFailsIfBlobLeaseCantBeAcquired(IBlobLease blobLeaseStub) { var leaseFactoryMock = new StubIBlobLeaseFactory { CreateLease_ICloudBlob = blob => blobLeaseStub }; var testBlob = _container.GetBlockBlobReference("testBlob"); await BlobUtils.CreateEmptyBlob(testBlob); UpdateBlob updateBlob = new UpdateBlob(testBlob, leaseFactoryMock); Assert.False(await updateBlob.TryLock()); }
private void DisposeLease() { _leaseId = null; _lease.Dispose(); _lease = null; }
public async Task <bool> TryStartUpdateSession(string applicationId) { string updateBlobName = GetUpdateBlobName(applicationId); bool started = false; try { ICloudBlob updateBlob = GetBlob(updateBlobName); await CreateBlobIfNoneExists(updateBlob); IBlobLease blobLease = _blobLeaseFactory.CreateLease(updateBlob); ExceptionDispatchInfo capturedException = null; string leaseId = await blobLease.TryAcquireLease(); // allow this instance to update only if it can acquire a lease on the blob. if (leaseId == null) { Trace.TraceInformation("Cannot start update session because unable to acquire the lease on the blob"); return(false); } try { var updateBlobWrapper = await UpdateBlobWrapper.Create(updateBlob); var updateDomain = updateBlobWrapper.GetUpdateDomain(); HashSet <string> updateDomainInstancesHashset = updateBlobWrapper.GetInstanceIds(); // allow this instance to try updating only if either one of the following conditions are true: // 1. no update domain is set, // 2. the current instance is in the same update domain // 3. no instances are set for the current update domain if (string.IsNullOrEmpty(updateDomain) || _config.InstanceUpdateDomain == updateDomain || updateDomainInstancesHashset.Count == 0) { Trace.TraceInformation( "Instance {0} acquired a lock on update blob {1} and will attempt to enlist itself", _config.InstanceId, updateBlobName); updateDomainInstancesHashset.Add(_config.InstanceId); await updateBlobWrapper.SetData(leaseId, _config.InstanceUpdateDomain, updateDomainInstancesHashset); Trace.TraceInformation("Instance {0} enlisted itself in the update blob", _config.InstanceId); started = true; } } catch (Exception e) { capturedException = ExceptionDispatchInfo.Capture(e); } await blobLease.ReleaseLease(); Trace.TraceInformation("Instance {0} released the lock on update blob {1}", _config.InstanceId, updateBlobName); if (capturedException != null) { capturedException.Throw(); } return(started); } catch (Exception ex) { throw new Exception("Failed to start update session ", ex); } }
public async Task EndUpdateSession(string applicationId) { string updateBlobName = GetUpdateBlobName(applicationId); var retryAttemptsRemaining = 10; var retryAttempts = retryAttemptsRemaining; bool failed = false; do { if (retryAttemptsRemaining-- == 0) { throw new Exception( string.Format("Instance {0} failed to update the update blob {1} after trying {2} times", _config.InstanceId, updateBlobName, retryAttempts)); } try { ICloudBlob updateBlob = GetBlob(updateBlobName); IBlobLease blobLease = _blobLeaseFactory.CreateLease(updateBlob); ExceptionDispatchInfo capturedException = null; string leaseId = await blobLease.TryAcquireLease(); if (leaseId != null) { Trace.TraceInformation( "Instance {0} acquired a lock on update blob {1} and will attempt to delist itself", _config.InstanceId, updateBlobName); try { UpdateBlobWrapper updateBlobWrapper = await UpdateBlobWrapper.Create(updateBlob); var updateDomain = updateBlobWrapper.GetUpdateDomain(); var updateDomainInstancesHashset = updateBlobWrapper.GetInstanceIds(); updateDomainInstancesHashset.Remove(_config.InstanceId); await updateBlobWrapper.SetData(leaseId, updateDomain, updateDomainInstancesHashset); Trace.TraceInformation("Instance {0} delisted itself from the update blob", _config.InstanceId); } catch (Exception e) { capturedException = ExceptionDispatchInfo.Capture(e); } finally { Trace.TraceInformation("Instance {0} released the lock on update blob {1}", _config.InstanceId, updateBlobName); } await blobLease.ReleaseLease(); if (capturedException != null) { capturedException.Throw(); } } else { throw new Exception( "Update session manager failed to end update session because it cannot Acquire the lease"); } } catch (Exception ex) { Trace.TraceError("Instance {0} failed to update the update blob {1}. Exception was: {2}", _config.InstanceId, updateBlobName, ex); failed = true; } if (failed) { await Task.Delay(1000); // allowing 1s between retries } } while (failed); }