public async Task <IDistributedLock> TryLockAsync( string account, string lockId, string lockOwnerId, string proposedLeaseId, TimeSpan lockPeriod, CancellationToken cancellationToken) { IStorageBlobDirectory lockDirectory = GetLockDirectory(account); IStorageBlockBlob lockBlob = lockDirectory.GetBlockBlobReference(lockId); string leaseId = await TryAcquireLeaseAsync(lockBlob, lockPeriod, proposedLeaseId, cancellationToken); if (string.IsNullOrEmpty(leaseId)) { return(null); } if (!string.IsNullOrEmpty(lockOwnerId)) { await WriteLeaseBlobMetadata(lockBlob, leaseId, lockOwnerId, cancellationToken); } SingletonLockHandle lockHandle = new SingletonLockHandle(leaseId, lockId, lockBlob, lockPeriod); return(lockHandle); }
public async virtual Task <object> TryLockAsync(string lockId, string functionInstanceId, SingletonAttribute attribute, CancellationToken cancellationToken, bool retry = true) { IStorageBlobDirectory lockDirectory = GetLockDirectory(attribute.Account); IStorageBlockBlob lockBlob = lockDirectory.GetBlockBlobReference(lockId); await TryCreateAsync(lockBlob, cancellationToken); _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Waiting for Singleton lock ({0})", lockId), source: TraceSource.Execution); TimeSpan lockPeriod = GetLockPeriod(attribute, _config); string leaseId = await TryAcquireLeaseAsync(lockBlob, lockPeriod, cancellationToken); if (string.IsNullOrEmpty(leaseId) && retry) { // Someone else has the lease. Continue trying to periodically get the lease for // a period of time TimeSpan acquisitionTimeout = attribute.LockAcquisitionTimeout != null ? TimeSpan.FromSeconds(attribute.LockAcquisitionTimeout.Value) : _config.LockAcquisitionTimeout; double remainingWaitTime = acquisitionTimeout.TotalMilliseconds; while (string.IsNullOrEmpty(leaseId) && remainingWaitTime > 0) { await Task.Delay(_config.LockAcquisitionPollingInterval); leaseId = await TryAcquireLeaseAsync(lockBlob, lockPeriod, cancellationToken); remainingWaitTime -= _config.LockAcquisitionPollingInterval.TotalMilliseconds; } } if (string.IsNullOrEmpty(leaseId)) { _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Unable to acquire Singleton lock ({0}).", lockId), source: TraceSource.Execution); return(null); } _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Singleton lock acquired ({0})", lockId), source: TraceSource.Execution); if (!string.IsNullOrEmpty(functionInstanceId)) { await WriteLeaseBlobMetadata(lockBlob, leaseId, functionInstanceId, cancellationToken); } SingletonLockHandle lockHandle = new SingletonLockHandle { LeaseId = leaseId, LockId = lockId, Blob = lockBlob, LeaseRenewalTimer = CreateLeaseRenewalTimer(lockBlob, leaseId, lockId, lockPeriod, _backgroundExceptionDispatcher) }; // start the renewal timer, which ensures that we maintain our lease until // the lock is released lockHandle.LeaseRenewalTimer.Start(); return(lockHandle); }
public async virtual Task ReleaseLockAsync(object lockHandle, CancellationToken cancellationToken) { SingletonLockHandle singletonLockHandle = (SingletonLockHandle)lockHandle; if (singletonLockHandle.LeaseRenewalTimer != null) { await singletonLockHandle.LeaseRenewalTimer.StopAsync(cancellationToken); } await ReleaseLeaseAsync(singletonLockHandle.Blob, singletonLockHandle.LeaseId, cancellationToken); _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Singleton lock released ({0})", singletonLockHandle.LockId), source: TraceSource.Execution); }
public async virtual Task<object> TryLockAsync(string lockId, string functionInstanceId, SingletonAttribute attribute, CancellationToken cancellationToken) { IStorageBlockBlob lockBlob = _directory.GetBlockBlobReference(lockId); await TryCreateAsync(lockBlob, cancellationToken); _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Waiting for Singleton lock ({0})", lockId), source: TraceSource.Execution); string leaseId = await TryAcquireLeaseAsync(lockBlob, _config.LockPeriod, cancellationToken); if (string.IsNullOrEmpty(leaseId)) { // Someone else has the lease. Continue trying to periodically get the lease for // a period of time TimeSpan acquisitionTimeout = attribute.LockAcquisitionTimeout != null ? TimeSpan.FromSeconds(attribute.LockAcquisitionTimeout.Value) : _config.LockAcquisitionTimeout; double remainingWaitTime = acquisitionTimeout.TotalMilliseconds; while (string.IsNullOrEmpty(leaseId) && remainingWaitTime > 0) { await Task.Delay(_config.LockAcquisitionPollingInterval); leaseId = await TryAcquireLeaseAsync(lockBlob, _config.LockPeriod, cancellationToken); remainingWaitTime -= _config.LockAcquisitionPollingInterval.TotalMilliseconds; } } if (string.IsNullOrEmpty(leaseId)) { _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Unable to acquire Singleton lock ({0}).", lockId), source: TraceSource.Execution); return null; } _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Singleton lock acquired ({0})", lockId), source: TraceSource.Execution); if (!string.IsNullOrEmpty(functionInstanceId)) { await WriteLeaseBlobMetadata(lockBlob, leaseId, functionInstanceId, cancellationToken); } SingletonLockHandle lockHandle = new SingletonLockHandle { LeaseId = leaseId, LockId = lockId, Blob = lockBlob, LeaseRenewalTimer = CreateLeaseRenewalTimer(lockBlob, leaseId, lockId, _config.LockPeriod, _backgroundExceptionDispatcher) }; // start the renewal timer, which ensures that we maintain our lease until // the lock is released lockHandle.LeaseRenewalTimer.Start(); return lockHandle; }
public async Task ReleaseLockAsync(IDistributedLock lockHandle, CancellationToken cancellationToken) { SingletonLockHandle singletonLockHandle = (SingletonLockHandle)lockHandle; await ReleaseLeaseAsync(singletonLockHandle.Blob, singletonLockHandle.LeaseId, cancellationToken); }
public Task <bool> RenewAsync(IDistributedLock lockHandle, CancellationToken cancellationToken) { SingletonLockHandle singletonLockHandle = (SingletonLockHandle)lockHandle; return(singletonLockHandle.RenewAsync(_trace, _logger, cancellationToken)); }