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>();
		}