public void No_deadlock_and_no_race_condition_on_resources_using_sessions() { var mgr = new LockManager(); var watch = new Stopwatch(); watch.Start(); int iterations = 10_000; Parallel.For(0, iterations, i => { Parallel.Invoke( () => { var session = Guid.NewGuid(); mgr.AcquireLock(session, false, "a", "b", "c"); ReadAbc(); mgr.CloseSession(session); }, () => { var session = Guid.NewGuid(); mgr.AcquireLock(session, false, "a"); ReadA(); mgr.CloseSession(session); }, () => { var session = Guid.NewGuid(); mgr.AcquireLock(session, true, "a", "b", "c"); WriteAbc(); mgr.CloseSession(session); }, () => { var session = Guid.NewGuid(); mgr.AcquireLock(session, true, "a"); WriteA(); mgr.CloseSession(session); }); }); watch.Stop(); Console.WriteLine($"{iterations} iterations took {watch.ElapsedMilliseconds} ms"); Console.WriteLine($"retries = {mgr.Retries}"); Console.WriteLine($"a = {_resourceA.Count} b = {_resourceB.Count} c = {_resourceC.Count}"); int locks = mgr.GetCurrentlyHoldLocks(); Assert.AreEqual(0, locks); }
public void Consistent_read_sessions() { ILockManager lockManager = new LockManager(null); var session = Guid.NewGuid(); lockManager.AcquireLock(session, false, "x", "y", "z"); bool success = lockManager.CheckLock(session, false, "x"); Assert.IsTrue(success); // try with a new session (should not work) success = lockManager.CheckLock(Guid.NewGuid(), false, "x"); Assert.IsFalse(success); // read-only lock so it should not work success = lockManager.CheckLock(session, true, "x"); Assert.IsFalse(success); // different resource so it should not work success = lockManager.CheckLock(session, true, "nope"); Assert.IsFalse(success); // trying to close an inactive session throws an exception Assert.Throws <NotSupportedException>(() => lockManager.CloseSession(Guid.NewGuid())); }
public void Managing_pending_locks() { var log = A.Fake <IEventsLog>(); ILockManager lockManager = new LockManager(log); var sessionId = Guid.NewGuid(); lockManager.AcquireLock(sessionId, false, "x", "y", "z"); Assert.AreEqual(3, lockManager.GetCurrentlyHoldLocks()); Assert.IsTrue(lockManager.CheckLock(sessionId, false, "x", "y", "z")); // false because it is a read-only lock Assert.False(lockManager.CheckLock(sessionId, true, "x", "y", "z")); lockManager.CloseSession(sessionId); Assert.AreEqual(0, lockManager.GetCurrentlyHoldLocks()); // session no longer active Assert.IsFalse(lockManager.CheckLock(sessionId, false, "x", "y", "z")); lockManager.AcquireLock(sessionId, true, "tony", "tara"); Assert.AreEqual(2, lockManager.GetCurrentlyHoldLocks()); Thread.Sleep(500); Assert.AreEqual(2, lockManager.GetCurrentlyHoldLocks(100)); var locks = lockManager.ForceRemoveAllLocks(100); A.CallTo(() => log.LogEvent(EventType.LockRemoved, null, 0)).MustHaveHappened(); Assert.AreEqual(2, locks); Assert.AreEqual(0, lockManager.GetCurrentlyHoldLocks()); }
public void Mixed_use_of_sessions_and_simple_accesses_simulating_both_transactional_and_non_transactional_clients() { var mgr = new LockManager(); var watch = new Stopwatch(); watch.Start(); int iterations = 100; Parallel.For(0, iterations, i => { Parallel.Invoke( () => { for (int i = 0; i < iterations; i++) { var session = Guid.NewGuid(); mgr.AcquireLock(session, false, "a", "b", "c"); ReadAbc(); mgr.CloseSession(session); } }, () => { for (int i = 0; i < iterations; i++) { var session = Guid.NewGuid(); mgr.AcquireLock(session, false, "a"); ReadA(); mgr.CloseSession(session); } }, () => { for (int i = 0; i < iterations; i++) { var session = Guid.NewGuid(); mgr.AcquireLock(session, true, "a", "b", "c"); WriteAbc(); mgr.CloseSession(session); } }, () => { for (int i = 0; i < iterations; i++) { var session = Guid.NewGuid(); mgr.AcquireLock(session, true, "a"); WriteA(); mgr.CloseSession(session); } }, () => { for (int i = 0; i < 100; i++) { mgr.DoWithReadLock(ReadAbc, "a", "b", "c"); } }, () => { for (int i = 0; i < 100; i++) { mgr.DoWithReadLock(ReadA, "a"); } }, () => { for (int i = 0; i < 100; i++) { mgr.DoWithWriteLock(WriteAbc, "a", "b", "c"); } }, () => { for (int i = 0; i < 100; i++) { mgr.DoWithWriteLock(WriteA, "a"); } }); }); watch.Stop(); Console.WriteLine($"{iterations} iterations took {watch.ElapsedMilliseconds} ms"); Console.WriteLine($"retries = {mgr.Retries}"); Console.WriteLine($"a = {_resourceA.Count} b = {_resourceB.Count} c = {_resourceC.Count}"); int locks = mgr.GetCurrentlyHoldLocks(); Assert.AreEqual(0, locks); }