public void LockCancellationToken_IsCancelled_AfterLosingLock() { var config = new RemoteLockerTesterConfig { LockersCount = 1, LocalRivalOptimization = LocalRivalOptimization.Disabled, LockTtl = TimeSpan.FromSeconds(5), LockMetadataTtl = TimeSpan.FromMinutes(1), KeepLockAliveInterval = TimeSpan.FromSeconds(3), ChangeLockRowThreshold = 10, TimestampProviderStochasticType = TimestampProviderStochasticType.None, CassandraClusterSettings = SingleCassandraNodeSetUpFixture.CreateCassandraClusterSettings(attempts: 1, timeout: TimeSpan.FromSeconds(1)), }; using (var tester = new RemoteLockerTester(config)) { var lockId = Guid.NewGuid().ToString(); using (var lock1 = tester[0].Lock(lockId)) { Assert.That(lock1.LockAliveToken.IsCancellationRequested, Is.False); // waiting more than LockTtl * 0.5 with no lock prolongation Thread.Sleep(config.KeepLockAliveInterval); Assert.That(lock1.LockAliveToken.IsCancellationRequested, Is.True); } } }
public void LockIsKeptAlive_Failure() { var config = new RemoteLockerTesterConfig { LockersCount = 2, LocalRivalOptimization = LocalRivalOptimization.Disabled, LockTtl = TimeSpan.FromSeconds(5), LockMetadataTtl = TimeSpan.FromMinutes(1), KeepLockAliveInterval = TimeSpan.FromSeconds(10), ChangeLockRowThreshold = 10, TimestampProviderStochasticType = TimestampProviderStochasticType.None, CassandraClusterSettings = SingleCassandraNodeSetUpFixture.CreateCassandraClusterSettings(attempts: 1, timeout: TimeSpan.FromSeconds(1)), }; using (var tester = new RemoteLockerTester(config)) { var lockId = Guid.NewGuid().ToString(); var lock1 = tester[0].Lock(lockId); Thread.Sleep(TimeSpan.FromSeconds(3)); Assert.That(tester[1].TryGetLock(lockId, out var lock2), Is.False); Thread.Sleep(TimeSpan.FromSeconds(4)); // waiting in total: 3 + 4 = 1*1 + 5 + 1 sec Assert.That(tester[1].TryGetLock(lockId, out lock2), Is.True); lock2.Dispose(); lock1.Dispose(); } }
public RemoteLockerTester(RemoteLockerTesterConfig config = null) { config = config ?? RemoteLockerTesterConfig.Default(); var localRivalOptimizationIsEnabled = config.LocalRivalOptimization != LocalRivalOptimization.Disabled; var serializer = new Serializer(new AllPropertiesExtractor(), null, GroBufOptions.MergeOnRead); ICassandraCluster cassandraCluster = new CassandraCluster(config.CassandraClusterSettings, logger); if (config.CassandraFailProbability.HasValue) { cassandraCluster = new FailedCassandraCluster(cassandraCluster, config.CassandraFailProbability.Value); } var timestampProvider = new StochasticTimestampProvider(config.TimestampProviderStochasticType, config.LockTtl); var implementationSettings = new CassandraRemoteLockImplementationSettings(timestampProvider, SingleCassandraNodeSetUpFixture.RemoteLockKeyspace, SingleCassandraNodeSetUpFixture.RemoteLockColumnFamily, config.LockTtl, config.LockMetadataTtl, config.KeepLockAliveInterval, config.ChangeLockRowThreshold); var cassandraRemoteLockImplementation = new CassandraRemoteLockImplementation(cassandraCluster, serializer, implementationSettings); remoteLockers = new RemoteLocker[config.LockersCount]; remoteLockerMetrics = new RemoteLockerMetrics("dummyKeyspace"); if (localRivalOptimizationIsEnabled) { var remoteLocker = new RemoteLocker(cassandraRemoteLockImplementation, remoteLockerMetrics, logger); for (var i = 0; i < config.LockersCount; i++) { remoteLockers[i] = remoteLocker; } } else { for (var i = 0; i < config.LockersCount; i++) { remoteLockers[i] = new RemoteLocker(new CassandraRemoteLockImplementation(cassandraCluster, serializer, implementationSettings), remoteLockerMetrics, logger); } } // it is important to use another CassandraCluster (with another setting of attempts, for example) cassandraRemoteLockImplementationForCheckings = new CassandraRemoteLockImplementation(new CassandraCluster(SingleCassandraNodeSetUpFixture.CreateCassandraClusterSettings(), logger), serializer, implementationSettings); }