public void EachViewStartsAtNextPositionAndWrapsOver() { var uris = Enumerable.Range(9200, NumberOfNodes).Select(p => new Uri("http://localhost:" + p)); var staticPool = new StickyConnectionPool(uris); this.AssertCreateView(staticPool); }
public void EachViewDoesNotSkip() { var seeds = Enumerable.Range(9200, NumberOfNodes).Select(p => new Node(new Uri("http://localhost:" + p))).ToList(); var pool = new StickyConnectionPool(seeds); for (var i = 0; i < 20; i++) { var node = pool.CreateView().First(); node.Uri.Port.Should().Be(9200); node = pool.CreateView().First(); node.Uri.Port.Should().Be(9200); node = pool.CreateView().First(); node.Uri.Port.Should().Be(9200); } }
public void AssertCreateView(StickyConnectionPool pool) { /** * Here we have setup a static connection pool seeded with 10 nodes. * So what order we expect? Imagine the following: * * Thread A calls GetNext and gets returned the first live node * Thread B calls GetNext() and gets returned the same node as it's still the first live. */ var startingPositions = Enumerable.Range(0, NumberOfNodes) .Select(i => pool.CreateView().First()) .Select(n => n.Uri.Port) .ToList(); var expectedOrder = Enumerable.Repeat(9200, NumberOfNodes); startingPositions.Should().ContainInOrder(expectedOrder); }
public void EachViewStartsAtNextPositionAndWrapsOver() { var numberOfNodes = 10; var uris = Enumerable.Range(9200, numberOfNodes).Select(p => new Uri("http://localhost:" + p)); var pool = new StickyConnectionPool(uris); /** * Here we have setup a sticky connection pool seeded with 10 nodes. * So what order we expect? Imagine the following: * * Thread A calls GetNext and gets returned the first live node * Thread B calls GetNext() and gets returned the same node as it's still the first live. */ var startingPositions = Enumerable.Range(0, numberOfNodes) .Select(i => pool.CreateView().First()) .Select(n => n.Uri.Port) .ToList(); var expectedOrder = Enumerable.Repeat(9200, numberOfNodes); startingPositions.Should().ContainInOrder(expectedOrder); }
public void ViewSeesResurrectedNodes() { var dateTimeProvider = new TestableDateTimeProvider(); var seeds = Enumerable.Range(9200, NumberOfNodes).Select(p => new Node(new Uri("http://localhost:" + p))).ToList(); seeds.First().MarkDead(dateTimeProvider.Now().AddDays(1)); var pool = new StickyConnectionPool(seeds, dateTimeProvider: dateTimeProvider); for (var i = 0; i < 20; i++) { var node = pool.CreateView().First(); node.Uri.Port.Should().Be(9201); node = pool.CreateView().First(); node.Uri.Port.Should().Be(9201); } /** If we forward our clock 2 days the node that was marked dead until tomorrow (or yesterday!) should be resurrected */ dateTimeProvider.ChangeTime(d => d.AddDays(2)); var n = pool.CreateView().First(); n.Uri.Port.Should().Be(9200); n = pool.CreateView().First(); n.Uri.Port.Should().Be(9200); n = pool.CreateView().First(); n.Uri.Port.Should().Be(9200); n.IsResurrected.Should().BeTrue(); }
public void EachViewSeesNextButSkipsTheDeadNode() { var seeds = Enumerable.Range(9200, NumberOfNodes).Select(p => new Node(new Uri("http://localhost:" + p))).ToList(); seeds.First().MarkDead(DateTime.Now.AddDays(1)); var pool = new StickyConnectionPool(seeds); for (var i = 0; i < 20; i++) { var node = pool.CreateView().First(); node.Uri.Port.Should().Be(9201); node = pool.CreateView().First(); node.Uri.Port.Should().Be(9201); } /** After we mark the first node alive again we expect it to be hit again*/ seeds.First().MarkAlive(); for (var i = 0; i < 20; i++) { var node = pool.CreateView().First(); node.Uri.Port.Should().Be(9200); node = pool.CreateView().First(); node.Uri.Port.Should().Be(9200); node = pool.CreateView().First(); node.Uri.Port.Should().Be(9200); } }
/**[[sticky-connection-pool]] * === StickyConnectionPool * A type of `IConnectionPool` that returns the first live node such that it is sticky between * requests. * It uses https://msdn.microsoft.com/en-us/library/system.threading.interlocked(v=vs.110).aspx[`System.Threading.Interlocked`] * to keep an _indexer_ to the last live node in a thread safe manner. */ [U] public void Sticky() { var uris = Enumerable.Range(9200, 5).Select(p => new Uri("http://localhost:" + p)); /** a connection pool can be seeded using an enumerable of `Uri` */ var pool = new StickyConnectionPool(uris); /** Or using an enumerable of `Node`. * A major benefit here is you can include known node roles when seeding and * NEST can use this information to favour sniffing on master eligible nodes first * and take master only nodes out of rotation for issuing client calls on. */ var nodes = uris.Select(u=>new Node(u)); pool = new StickyConnectionPool(nodes); /** This type of pool is hardwired to opt out of reseeding (and hence sniffing)*/ pool.SupportsReseeding.Should().BeFalse(); /** but does support pinging */ pool.SupportsPinging.Should().BeTrue(); /** To create a client using the sticky connection pool pass * the connection pool to the `ConnectionSettings` you pass to `ElasticClient` */ var client = new ElasticClient(new ConnectionSettings(pool)); client.ConnectionSettings.ConnectionPool.Should().BeOfType<StickyConnectionPool>(); }