public async Task Acquire_lock_multiple_times_work()
        {
            const string lockName = "my-lock";

            var locker = new SqlServerDistributedAppLockProvider(_connectionFactory,
                                                                 new SqlServerDistributedAppLockConfig
            {
                DisposeDbConnection = false
            });

            using (await locker.AcquireAsync(lockName))
            {
                // mutual exclusion scope here
            }

            using (await locker.AcquireAsync(lockName))
            {
                // mutual exclusion scope here
            }

            using (await locker.AcquireAsync(lockName))
            {
                // mutual exclusion scope here
            }
        }
        public void Test_that_is_acquired_is_false_when_disposed()
        {
            var provider = new SqlServerDistributedAppLockProvider(_connectionFactory);
            var theLock  = provider.Acquire("this-is-my-lock");

            theLock.Dispose();
            Assert.False(theLock.IsActive);
        }
        public async Task Throws_if_given_connection_is_not_open()
        {
            var locker = new SqlServerDistributedAppLockProvider(() => new SqlConnection(_connectionString));
            var ex     = await Assert.ThrowsAsync <DistributedAppLockException>(async() => { await locker.AcquireAsync("TheLock"); });

            var arEx = Assert.IsAssignableFrom <ArgumentException>(ex.InnerException);

            Assert.Equal("dbConnection", arEx.ParamName);
        }
        public void Acquire_sync_also_works()
        {
            const string lockName = "my-lock";
            var          locker   = new SqlServerDistributedAppLockProvider(_connectionFactory);

            using (locker.Acquire(lockName))
            {
                // mutual exclusion scope here
            }
        }
        public async Task Acquire_with_auto_expiry_throws()
        {
            var ex = await Assert.ThrowsAsync <DistributedAppLockException>(async() =>
            {
                var locker = new SqlServerDistributedAppLockProvider(_connectionFactory);
                await locker.AcquireAsync("theLock", TimeSpan.Zero, TimeSpan.MaxValue);
            });

            Assert.IsAssignableFrom <NotSupportedException>(ex.InnerException);
        }
Esempio n. 6
0
        public void Test_acquire_lock_with_timeout_works()
        {
            /*
             * This test flow goes something like:
             * 1. acquire firstLock
             * 2. Start a new thread that immediately returns and waits for a while
             * 3. Try to acquire second lock, but be patient and wait for up to 20 secs while retrying
             * 4. thread unlocks first lock after 700 ms
             * 5. thread waits 500 ms
             * 6. now we expect the second call to acquire to have succeeded, assert that this is true
             */
            SqlServerDistributedAppLock firstLock  = null;
            SqlServerDistributedAppLock secondLock = null;
            var lockName = "some-other-lock";

            var locker = new SqlServerDistributedAppLockProvider(_connectionFactory);

            firstLock = (SqlServerDistributedAppLock)locker.Acquire(lockName, TimeSpan.FromSeconds(1));
            Assert.True(firstLock.WasAcquiredInstantly);

            var threadStarted = false;

            // Create task to dispose of lock at some point
            Task.Factory.StartNew(() =>
            {
                threadStarted = true;

                // Wait 700 ms to allow the main thread to start acquiring second lock
                var timeStart = DateTime.UtcNow;
                while (DateTime.UtcNow.Subtract(timeStart).TotalMilliseconds < 700)
                {
                    // Do nothing
                }

                // release the first lock
                firstLock.Dispose();

                // wait and the new lock should be acquired
                Task.Delay(TimeSpan.FromMilliseconds(500));
                Assert.Equal(lockName, secondLock.Name);
                Assert.True(secondLock.IsActive);
                Assert.False(secondLock.WasAcquiredInstantly);
                Assert.True(secondLock.TimeUsedToAcquire.Ticks > 0);
                secondLock.Dispose();
            });

            // Thread creation can take some time
            // This waits for the thread to be created
            SpinWait.SpinUntil(() => threadStarted);

            // this second lock now enters retry mode
            secondLock = (SqlServerDistributedAppLock)locker.Acquire(lockName, TimeSpan.FromSeconds(20));
        }
        public async Task Default_behavior_disposes_connection()
        {
            var hasBeenDisposed = false;

            _connection.Disposed += (sender, args) => { hasBeenDisposed = true; };

            var provider = new SqlServerDistributedAppLockProvider(_connectionFactory);
            var handle   = await provider.AcquireAsync("some-lock");

            handle.Dispose();

            await Task.Delay(50);

            Assert.True(hasBeenDisposed);
            Assert.Equal(ConnectionState.Closed, _connection.State);
        }
        public async Task Configured_behavior_leaves_connection_intact()
        {
            var hasBeenDisposed = false;

            _connection.Disposed += (sender, args) => { hasBeenDisposed = true; };

            var provider = new SqlServerDistributedAppLockProvider(_connectionFactory,
                                                                   new SqlServerDistributedAppLockConfig
            {
                DisposeDbConnection = false
            });

            var handle = await provider.AcquireAsync("some-lock");

            handle.Dispose();

            await Task.Delay(50);

            Assert.False(hasBeenDisposed);
            Assert.Equal(ConnectionState.Open, _connection.State);
        }
        public void Cannot_acquire_lock_twice()
        {
            const string lockName = "second-lock";

            var locker = new SqlServerDistributedAppLockProvider(_connectionFactory);

            using (locker.Acquire(lockName, TimeSpan.FromSeconds(1)))
            {
                var ex = Assert.Throws <DistributedAppLockException>(() =>
                {
                    // we have to create a new connection here as taking the lock twice via the same connection is OK
                    var otherLocker = new SqlServerDistributedAppLockProvider(() =>
                    {
                        var conn = new SqlConnection(_connectionString);
                        conn.Open();

                        return(conn);
                    });
                    return(otherLocker.Acquire(lockName));
                });
                Assert.Equal(DistributedAppLockExceptionReason.LockAlreadyAcquired, ex.Reason);
            }
        }