public void TestIdleSessionKiller() { // This makes sure that for the Semaphore5 lock initial 4 tickets are taken with the default // application name and therefore won't be counted or killed this._lockProvider.CreateLock(nameof(TestIdleSessionKiller)); var applicationName = this._lockProvider.Strategy.Db.SetUniqueApplicationName(); var @lock = this._lockProvider.CreateLock(nameof(TestIdleSessionKiller)); // go through one acquire/dispose cycle to ensure all commands are prepared. Due to // https://github.com/npgsql/npgsql/issues/2912 in Postgres, we get NRE on the post-kill Dispose() // call rather than the DbException we expected. @lock.Acquire().Dispose(); using var handle = @lock.Acquire(); this._lockProvider.Strategy.Db.CountActiveSessions(applicationName).ShouldEqual(1); using var idleSessionKiller = new IdleSessionKiller(this._lockProvider.Strategy.Db, applicationName, idleTimeout: TimeSpan.FromSeconds(.1)); var stopwatch = Stopwatch.StartNew(); while (true) { Thread.Sleep(TimeSpan.FromSeconds(.02)); if (this._lockProvider.Strategy.Db.CountActiveSessions(applicationName) == 0) { break; } if (stopwatch.Elapsed > TimeSpan.FromSeconds(5)) { Assert.Fail("Timed out waiting for idle session to be killed"); } } Assert.Catch <DbException>(() => handle.Dispose()); }
[NonParallelizable, Retry(5)] // timing-sensitive public void TestKeepaliveProtectsFromIdleSessionKiller() { var applicationName = this._lockProvider.Strategy.SetUniqueApplicationName(); this._lockProvider.Strategy.KeepaliveCadence = TimeSpan.FromSeconds(.05); var @lock = this._lockProvider.CreateLock(Guid.NewGuid().ToString()); // use unique name due to retry var handle = @lock.Acquire(); using var idleSessionKiller = new IdleSessionKiller(this._lockProvider.Strategy.Db, applicationName, idleTimeout: TimeSpan.FromSeconds(.5)); Thread.Sleep(TimeSpan.FromSeconds(2)); Assert.DoesNotThrow(() => handle.Dispose()); }
[NonParallelizable, Retry(tryCount: 5)] // this test is somewhat timing sensitive public void TestKeepaliveProtectsFromIdleSessionKillerAfterFailedUpgrade() { var applicationName = this._lockProvider.Strategy.SetUniqueApplicationName(); this._lockProvider.Strategy.KeepaliveCadence = TimeSpan.FromSeconds(.1); var @lock = this._lockProvider.CreateUpgradeableReaderWriterLock(Guid.NewGuid().ToString()); using var idleSessionKiller = new IdleSessionKiller(this._lockProvider.Strategy.Db, applicationName, idleTimeout: TimeSpan.FromSeconds(.5)); using (@lock.AcquireReadLock()) { var handle = @lock.AcquireUpgradeableReadLock(); handle.TryUpgradeToWriteLock().ShouldEqual(false); handle.TryUpgradeToWriteLockAsync().Result.ShouldEqual(false); Thread.Sleep(TimeSpan.FromSeconds(1)); Assert.DoesNotThrow(() => handle.Dispose()); } }