public void NodeDisposeTest() { // Memcache client config var config = new MemcacheClientConfiguration { TransportFactory = (_, __, r, s, ___, ____) => { var transport = new TransportMock(r) { IsAlive = true, Setup = s }; if (s != null) s(transport); return transport; }, PoolSize = 1, }; var node = new MemcacheNode(null, config); // TransportMock does not put back the transport in the pool after the TrySend Assert.IsTrue(node.TrySend(new NoOpRequest(), 5000), "Unable to send a request through the node"); // Dispose the node after a certain delay ThreadPool.QueueUserWorkItem((o) => { Thread.Sleep(500); node.Dispose(); }); // The following TrySend will block because the transport pool is empty Assert.DoesNotThrow(() => node.TrySend(new NoOpRequest(), 1000), "The TrySend should not throw an exception"); }
public void SyncNodeDeadDetection() { bool aliveness = true; var transportMocks = new List<TransportMock>(); var config = new MemcacheClientConfiguration { DeadTimeout = TimeSpan.FromSeconds(1), TransportFactory = (_, __, r, s, ___, ____) => { var transport = new TransportMock(r) { IsAlive = aliveness, Setup = s }; transportMocks.Add(transport); if (s != null) s(transport); return transport; }, PoolSize = 2, }; var node = new MemcacheNode(null, config); CollectionAssert.IsNotEmpty(transportMocks, "No transport has been created by the node"); Assert.IsTrue(node.TrySend(new NoOpRequest(), 5000), "Unable to send a request through the node"); // creation of new transport will set them as dead aliveness = false; foreach (var transport in transportMocks) transport.IsAlive = false; Assert.IsFalse(node.TrySend(new NoOpRequest(), 5000), "The node did not failed with all transport deads"); foreach (var transport in transportMocks) transport.IsAlive = true; Assert.IsFalse(node.IsDead, "The node is still dead, should be alive now !"); Assert.IsTrue(node.TrySend(new NoOpRequest(), 5000), "Unable to send a request throught the node after it's alive"); }