public async Task TryLockAsync_CreatesBlob_WhenItDoesNotExist()
        {
            CancellationToken cancellationToken = new CancellationToken();
            RequestResult     storageResult     = new RequestResult
            {
                HttpStatusCode = 404
            };
            StorageException storageException = new StorageException(storageResult, null, null);

            int count = 0;

            _mockStorageBlob.Setup(p => p.AcquireLeaseAsync(_singletonConfig.LockPeriod, null, cancellationToken)).Returns(() =>
            {
                if (count++ == 0)
                {
                    throw storageException;
                }
                return(Task.FromResult(TestLeaseId));
            });

            _mockStorageBlob.Setup(p => p.UploadTextAsync(string.Empty, null, null, null, null, cancellationToken)).Returns(Task.FromResult(true));
            _mockStorageBlob.SetupGet(p => p.Metadata).Returns(_mockBlobMetadata);
            _mockStorageBlob.Setup(p => p.SetMetadataAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));
            _mockStorageBlob.Setup(p => p.ReleaseLeaseAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));

            SingletonAttribute  attribute  = new SingletonAttribute();
            RenewableLockHandle lockHandle = await _singletonManager.TryLockAsync(TestLockId, TestInstanceId, attribute, cancellationToken);

            var innerHandle = lockHandle.GetInnerHandle();

            Assert.Same(_mockStorageBlob.Object, innerHandle.Blob);
            Assert.Equal(TestLeaseId, innerHandle.LeaseId);
            Assert.Equal(1, _mockStorageBlob.Object.Metadata.Keys.Count);
            Assert.Equal(_mockStorageBlob.Object.Metadata[BlobLeaseDistributedLockManager.FunctionInstanceMetadataKey], TestInstanceId);
        }
Ejemplo n.º 2
0
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            // When recovery is enabled, we don't do retries on the individual lock attempts,
            // since retries are being done outside
            bool recoveryEnabled = _singletonConfig.ListenerLockRecoveryPollingInterval != TimeSpan.MaxValue;

            _lockHandle = await _singletonManager.TryLockAsync(_lockId, null, _attribute, cancellationToken, retry : !recoveryEnabled);

            if (_lockHandle == null)
            {
                string msg = string.Format(CultureInfo.InvariantCulture, "Unable to acquire Singleton lock ({0}).", _lockId);
                _logger?.LogDebug(msg);

                // If we're unable to acquire the lock, it means another listener
                // has it so we return w/o starting our listener.
                //
                // However, we also start a periodic background "recovery" timer that will recheck
                // occasionally for the lock. This ensures that if the host that has the lock goes
                // down for whatever reason, others will have a chance to resume the work.
                if (recoveryEnabled)
                {
                    LockTimer          = new System.Timers.Timer(_singletonConfig.ListenerLockRecoveryPollingInterval.TotalMilliseconds);
                    LockTimer.Elapsed += OnLockTimer;
                    LockTimer.Start();
                }
                return;
            }

            await _innerListener.StartAsync(cancellationToken);

            _isListening = true;
        }
Ejemplo n.º 3
0

        
 public static SingletonLockHandle GetInnerHandle(this RenewableLockHandle handle)
 {
     if (handle == null)
     {
         return(null);
     }
     return((SingletonLockHandle)handle.InnerLock);
 }
Ejemplo n.º 5
0
        private async Task ReleaseLockAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            if (_lockHandle != null)
            {
                await _singletonManager.ReleaseLockAsync(_lockHandle, cancellationToken);

                _lockHandle = null;
            }
        }
        public async Task StartAsync_StartsListener_WhenLockAcquired()
        {
            CancellationToken cancellationToken = new CancellationToken();
            var lockHandle = new RenewableLockHandle(new SingletonLockHandle(), null);

            _mockSingletonManager.Setup(p => p.TryLockAsync(_lockId, null, _attribute, cancellationToken, false))
            .ReturnsAsync(lockHandle);
            _mockInnerListener.Setup(p => p.StartAsync(cancellationToken)).Returns(Task.FromResult(true));

            await _listener.StartAsync(cancellationToken);

            Assert.Null(_listener.LockTimer);

            _mockSingletonManager.VerifyAll();
            _mockInnerListener.VerifyAll();
        }
Ejemplo n.º 7
0
        internal async Task TryAcquireLock()
        {
            _lockHandle = await _singletonManager.TryLockAsync(_lockId, null, _attribute, CancellationToken.None, retry : false);

            if (_lockHandle != null)
            {
                if (LockTimer != null)
                {
                    LockTimer.Stop();
                    LockTimer.Dispose();
                    LockTimer = null;
                }

                await _innerListener.StartAsync(CancellationToken.None);

                _isListening = true;
            }
        }
        public async Task Dispose_WhenLockAcquired_ReleasesLock()
        {
            CancellationToken cancellationToken = new CancellationToken();
            var lockHandle = new RenewableLockHandle(new SingletonLockHandle(), null);

            _mockSingletonManager.Setup(p => p.TryLockAsync(_lockId, null, _attribute, cancellationToken, false))
            .ReturnsAsync(lockHandle);
            _mockInnerListener.Setup(p => p.StartAsync(cancellationToken)).Returns(Task.FromResult(true));

            await _listener.StartAsync(cancellationToken);

            _mockInnerListener.Setup(p => p.Dispose());
            _mockSingletonManager.Setup(p => p.ReleaseLockAsync(lockHandle, cancellationToken)).Returns(Task.FromResult(true));

            _listener.Dispose();

            _mockSingletonManager.VerifyAll();
            _mockInnerListener.VerifyAll();
        }
        public async Task TryAcquireLock_WhenLockAcquired_StopsLockTimerAndStartsListener()
        {
            _listener.LockTimer = new System.Timers.Timer
            {
                Interval = 30 * 1000
            };
            _listener.LockTimer.Start();

            RenewableLockHandle lockHandle = new RenewableLockHandle(new SingletonLockHandle(), null);

            _mockSingletonManager.Setup(p => p.TryLockAsync(_lockId, null, _attribute, CancellationToken.None, false))
            .ReturnsAsync(lockHandle);

            _mockInnerListener.Setup(p => p.StartAsync(CancellationToken.None)).Returns(Task.FromResult(true));

            await _listener.TryAcquireLock();

            Assert.Null(_listener.LockTimer);
        }
Ejemplo n.º 10
0
        public async Task ReleaseLockAsync_StopsRenewalTimerAndReleasesLease()
        {
            CancellationToken cancellationToken = new CancellationToken();

            Mock<ITaskSeriesTimer> mockRenewalTimer = new Mock<ITaskSeriesTimer>(MockBehavior.Strict);
            mockRenewalTimer.Setup(p => p.StopAsync(cancellationToken)).Returns(Task.FromResult(true));

            _mockStorageBlob.Setup(p => p.ReleaseLeaseAsync(It.Is<AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));

            var handle = new RenewableLockHandle(
                new SingletonLockHandle
                {
                    Blob = _mockStorageBlob.Object,
                    LeaseId = TestLeaseId
                },
                mockRenewalTimer.Object
            );

            await _singletonManager.ReleaseLockAsync(handle, cancellationToken);

            mockRenewalTimer.VerifyAll();
        }