Skip to content

Commit 2b4d598

Browse files
committed
Improve connection pooling docs
This commit improves the connection pooling docs by hiding test assertions from being output in documentation, and linking to sniffing and pinging behaviour docs. (cherry picked from commit c94ce95)
1 parent 191dfc9 commit 2b4d598

File tree

2 files changed

+197
-279
lines changed

2 files changed

+197
-279
lines changed

docs/client-concepts/connection-pooling/building-blocks/connection-pooling.asciidoc

Lines changed: 51 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -59,51 +59,25 @@ your cluster through a single load balancer instance.
5959
----
6060
var uri = new Uri("http://localhost:9201");
6161
var pool = new SingleNodeConnectionPool(uri);
62-
pool.Nodes.Should().HaveCount(1);
63-
var node = pool.Nodes.First();
64-
node.Uri.Port.Should().Be(9201);
62+
var client = new ElasticClient(new ConnectionSettings(pool));
6563
----
6664

67-
This type of pool is hardwired to opt out of reseeding (thus, sniffing) as well as pinging
68-
69-
[source,csharp]
70-
----
71-
pool.SupportsReseeding.Should().BeFalse();
72-
pool.SupportsPinging.Should().BeFalse();
73-
----
65+
This type of pool is hardwired to opt out of reseeding (<<sniffing-behaviour, sniffing>>) as well as <<pinging-behaviour, pinging>>
7466

7567
When you use the low ceremony `ElasticClient` constructor that takes a single `Uri`,
7668
internally a `SingleNodeConnectionPool` is used
7769

7870
[source,csharp]
7971
----
80-
var client = new ElasticClient(uri);
81-
client.ConnectionSettings.ConnectionPool
82-
.Should().BeOfType<SingleNodeConnectionPool>();
83-
----
84-
85-
However we urge that you always pass your connection settings explicitly
86-
87-
[source,csharp]
88-
----
89-
client = new ElasticClient(new ConnectionSettings(uri));
90-
client.ConnectionSettings.ConnectionPool
91-
.Should().BeOfType<SingleNodeConnectionPool>();
72+
client = new ElasticClient(uri);
9273
----
9374

94-
or even better pass the connection pool explicitly
95-
96-
[source,csharp]
97-
----
98-
client = new ElasticClient(new ConnectionSettings(pool));
99-
client.ConnectionSettings.ConnectionPool
100-
.Should().BeOfType<SingleNodeConnectionPool>();
101-
----
75+
However we encourage you to pass connection settings explicitly.
10276

10377
[[cloud-connection-pool]]
10478
==== CloudConnectionPool
10579

106-
A specialized subclass of `SingleNodeConnectionPool that accepts a Cloud Id and credentials.
80+
A specialized subclass of `SingleNodeConnectionPool` that accepts a Cloud Id and credentials.
10781
When used the client will also pick Elastic Cloud optmized defaults for the connection settings.
10882

10983
A Cloud Id for your cluster can be fetched from your Elastic Cloud cluster administration console.
@@ -114,67 +88,26 @@ A Cloud Id should be in the form of `cluster_name:base_64_data` where `base_64_d
11488

11589
Out of these, only `host_name` and `elasticsearch_uuid` are always available.
11690

117-
[source,csharp]
118-
----
119-
string ToBase64(string s) => Convert.ToBase64String(Encoding.UTF8.GetBytes(s));
120-
/* Here we obviously use a ficticuous Cloud Id so lets create a fake one. */
121-
122-
var hostName = "cloud-endpoint.example";
123-
var elasticsearchUuid = "3dadf823f05388497ea684236d918a1a";
124-
var services = $"{hostName}${elasticsearchUuid}$3f26e1609cf54a0f80137a80de560da4";
125-
var cloudId = $"my_cluster:{ToBase64(services)}";
126-
127-
/*
128-
* In a real scenario you would be able to copy paste `cloudId`
129-
*
130-
* A cloud connection pool always needs credentials as well here opt for basic auth
131-
*/
132-
var credentials = new BasicAuthenticationCredentials("username", "password");
133-
var pool = new CloudConnectionPool(cloudId, credentials);
134-
pool.UsingSsl.Should().BeTrue();
135-
pool.Nodes.Should().HaveCount(1);
136-
var node = pool.Nodes.First();
137-
node.Uri.Port.Should().Be(443);
138-
node.Uri.Host.Should().Be($"{elasticsearchUuid}.{hostName}");
139-
node.Uri.Scheme.Should().Be("https");
140-
----
141-
142-
This type of pool like its parent the `SingleNodeConnectionPool` is hardwired to opt out of
143-
reseeding (thus, sniffing) as well as pinging
91+
A cloud connection pool can be created using credentials and a `cloudId`
14492

14593
[source,csharp]
14694
----
147-
pool.SupportsReseeding.Should().BeFalse();
148-
pool.SupportsPinging.Should().BeFalse();
95+
var credentials = new BasicAuthenticationCredentials("username", "password"); <1>
96+
var pool = new CloudConnectionPool(cloudId, credentials); <2>
97+
var client = new ElasticClient(new ConnectionSettings(pool));
14998
----
99+
<1> a username and password that can access Elasticsearch service on Elastic Cloud
150100

151-
You can also directly create a cloud enabled connection using the clients constructor
101+
<2> `cloudId` is a value that can be retrieved from the Elastic Cloud web console
152102

153-
[source,csharp]
154-
----
155-
var client = new ElasticClient(cloudId, credentials);
156-
client.ConnectionSettings.ConnectionPool
157-
.Should()
158-
.BeOfType<CloudConnectionPool>();
159-
----
103+
This type of pool, like its parent the `SingleNodeConnectionPool`, is hardwired to opt out of
104+
reseeding (<<sniffing-behaviour, sniffing>>) as well as <<pinging-behaviour, pinging>>.
160105

161-
However we urge that you always pass your connection settings explicitly
106+
You can also directly create a cloud enabled connection using the `ElasticClient`'s constructor
162107

163108
[source,csharp]
164109
----
165-
client = new ElasticClient(new ConnectionSettings(pool));
166-
client.ConnectionSettings.ConnectionPool.Should().BeOfType<CloudConnectionPool>();
167-
168-
client.ConnectionSettings.EnableHttpCompression.Should().BeTrue();
169-
client.ConnectionSettings.BasicAuthenticationCredentials.Should().NotBeNull();
170-
client.ConnectionSettings.BasicAuthenticationCredentials.Username.Should().Be("username");
171-
foreach (var id in badCloudIds)
172-
{
173-
Action create = () => new ElasticClient(id, credentials);
174-
175-
create.Should().Throw<ArgumentException>()
176-
.And.Message.Should().Contain("should be a string in the form of cluster_name:base_64_data");
177-
}
110+
client = new ElasticClient(cloudId, credentials);
178111
----
179112

180113
[[static-connection-pool]]
@@ -183,17 +116,20 @@ foreach (var id in badCloudIds)
183116
The static connection pool is great if you have a known small sized cluster and do no want to enable
184117
sniffing to find out the cluster topology.
185118

119+
Given a collection of `Uri`
120+
186121
[source,csharp]
187122
----
188123
var uris = Enumerable.Range(9200, 5)
189124
.Select(port => new Uri($"http://localhost:{port}"));
190125
----
191126

192-
a connection pool can be seeded using an enumerable of `Uri`
127+
a connection pool can be seeded with this collection
193128

194129
[source,csharp]
195130
----
196131
var pool = new StaticConnectionPool(uris);
132+
var client = new ElasticClient(new ConnectionSettings(pool));
197133
----
198134

199135
Or using an enumerable of `Node`
@@ -202,33 +138,20 @@ Or using an enumerable of `Node`
202138
----
203139
var nodes = uris.Select(u => new Node(u));
204140
pool = new StaticConnectionPool(nodes);
141+
client = new ElasticClient(new ConnectionSettings(pool));
205142
----
206143

207144
This type of pool is hardwired to opt out of reseeding
208-
(and hence sniffing) but supports pinging when enabled
209-
210-
[source,csharp]
211-
----
212-
pool.SupportsReseeding.Should().BeFalse();
213-
pool.SupportsPinging.Should().BeTrue();
214-
----
215-
216-
To create a client using the static connection pool, pass
217-
the connection pool to the `ConnectionSettings` you pass to `ElasticClient`
218-
219-
[source,csharp]
220-
----
221-
var client = new ElasticClient(new ConnectionSettings(pool));
222-
client.ConnectionSettings.ConnectionPool
223-
.Should().BeOfType<StaticConnectionPool>();
224-
----
145+
(<<sniffing-behaviour, sniffing>>) but supports <<pinging-behaviour, pinging>> when enabled.
225146

226147
[[sniffing-connection-pool]]
227148
==== SniffingConnectionPool
228149

229150
A pool derived from `StaticConnectionPool`, a sniffing connection pool allows itself to be reseeded at run time.
230151
It comes with the very minor overhead of a `ReaderWriterLockSlim` to ensure thread safety.
231152

153+
Given a collection of `Uri`
154+
232155
[source,csharp]
233156
----
234157
var uris = Enumerable.Range(9200, 5)
@@ -240,36 +163,21 @@ a connection pool can be seeded using an enumerable of `Uri`
240163
[source,csharp]
241164
----
242165
var pool = new SniffingConnectionPool(uris);
166+
var client = new ElasticClient(new ConnectionSettings(pool));
243167
----
244168

245169
Or using an enumerable of `Node`. A major benefit in using nodes is that you can include
246-
known node roles when seeding which
247-
NEST can use to favour sniffing on master eligible nodes first,
248-
and take master only nodes out of rotation for issuing client calls on.
170+
known node roles when seeding, which NEST can then use to favour particular API requests. For example,
171+
sniffing on master eligible nodes first, and take master only nodes out of rotation for issuing client calls on.
249172

250173
[source,csharp]
251174
----
252175
var nodes = uris.Select(u=>new Node(u));
253176
pool = new SniffingConnectionPool(nodes);
177+
client = new ElasticClient(new ConnectionSettings(pool));
254178
----
255179

256-
This type of pool is hardwired to opt in to reseeding (and hence sniffing), and pinging
257-
258-
[source,csharp]
259-
----
260-
pool.SupportsReseeding.Should().BeTrue();
261-
pool.SupportsPinging.Should().BeTrue();
262-
----
263-
264-
To create a client using the sniffing connection pool pass
265-
the connection pool to the `ConnectionSettings` you pass to `ElasticClient`
266-
267-
[source,csharp]
268-
----
269-
var client = new ElasticClient(new ConnectionSettings(pool));
270-
client.ConnectionSettings.ConnectionPool
271-
.Should().BeOfType<SniffingConnectionPool>();
272-
----
180+
This type of pool is hardwired to opt in to reseeding (<<sniffing-behaviour, sniffing>>), and <<pinging-behaviour, pinging>>
273181

274182
[[sticky-connection-pool]]
275183
==== StickyConnectionPool
@@ -278,6 +186,8 @@ A type of connection pool that returns the first live node to issue a request ag
278186
It uses https://msdn.microsoft.com/en-us/library/system.threading.interlocked(v=vs.110).aspx[`System.Threading.Interlocked`]
279187
to keep an _indexer_ to the last live node in a thread safe manner.
280188

189+
Given a collection of `Uri`
190+
281191
[source,csharp]
282192
----
283193
var uris = Enumerable.Range(9200, 5)
@@ -289,72 +199,54 @@ a connection pool can be seeded using an enumerable of `Uri`
289199
[source,csharp]
290200
----
291201
var pool = new StickyConnectionPool(uris);
202+
var client = new ElasticClient(new ConnectionSettings(pool));
292203
----
293204

294-
Or using an enumerable of `Node`.
295-
A major benefit here is you can include known node roles when seeding and
296-
NEST can use this information to favour sniffing on master eligible nodes first
297-
and take master only nodes out of rotation for issuing client calls on.
205+
Or using an enumerable of `Node`, similar to `SniffingConnectionPool`
298206

299207
[source,csharp]
300208
----
301209
var nodes = uris.Select(u=>new Node(u));
302210
pool = new StickyConnectionPool(nodes);
211+
client = new ElasticClient(new ConnectionSettings(pool));
303212
----
304213

305-
This type of pool is hardwired to opt out of reseeding (and hence sniffing), but does support sniffing
306-
307-
[source,csharp]
308-
----
309-
pool.SupportsReseeding.Should().BeFalse();
310-
pool.SupportsPinging.Should().BeTrue();
311-
----
312-
313-
To create a client using the sticky connection pool pass
314-
the connection pool to the `ConnectionSettings` you pass to `ElasticClient`
315-
316-
[source,csharp]
317-
----
318-
var client = new ElasticClient(new ConnectionSettings(pool));
319-
client.ConnectionSettings.ConnectionPool
320-
.Should().BeOfType<StickyConnectionPool>();
321-
----
214+
This type of pool is hardwired to opt out of reseeding (<<sniffing-behaviour, sniffing>>), but does support <<pinging-behaviour, pinging>>.
322215

323216
[[sticky-sniffing-connection-pool]]
324217
==== Sticky Sniffing Connection Pool
325218

326219
A type of connection pool that returns the first live node to issue a request against, such that the node is _sticky_ between requests.
327-
This implementation supports sniffing and sorting so that each instance of your application can favor a node in the same rack based
328-
on node attributes for instance.
220+
This implementation supports sniffing and sorting so that each instance of your application can favour a node. For example,
221+
a node in the same rack, based on node attributes.
222+
223+
Given a collection of `Uri`
329224

330225
[source,csharp]
331226
----
332227
var uris = Enumerable.Range(9200, 5)
333228
.Select(port => new Uri($"http://localhost:{port}"));
334229
----
335230

336-
a sniffing sorted sticky pool takes a second parameter `Func` takes a Node and returns a weight.
337-
Nodes will be sorted descending by weight. In the following example we score nodes that are client nodes
338-
AND in rack_id `rack_one` the highest
231+
a sniffing sorted sticky pool takes a second parameter, a delegate of `Func<Node, float>`, that takes a Node and returns a weight.
232+
Nodes will be sorted in descending order by weight. In the following example, nodes are scored so that client nodes
233+
in rack_id `rack_one` score the highest
339234

340235
[source,csharp]
341236
----
342-
var pool = new StickySniffingConnectionPool(uris, n =>
343-
(n.ClientNode ? 10 : 0)
344-
+ (n.Settings.TryGetValue("node.attr.rack_id", out var rackId)
345-
&& rackId.ToString() == "rack_one" ? 10 : 0));
237+
var pool = new StickySniffingConnectionPool(uris, node =>
238+
{
239+
var weight = 0f;
346240
347-
pool.SupportsReseeding.Should().BeTrue();
348-
pool.SupportsPinging.Should().BeTrue();
349-
----
241+
if (node.ClientNode)
242+
weight += 10;
350243
351-
To create a client using the sticky sniffing connection pool pass
352-
the connection pool to the `ConnectionSettings` you pass to `ElasticClient`
244+
if (node.Settings.TryGetValue("node.attr.rack_id", out var rackId) && rackId.ToString() == "rack_one")
245+
weight += 10;
246+
247+
return weight;
248+
});
353249
354-
[source,csharp]
355-
----
356250
var client = new ElasticClient(new ConnectionSettings(pool));
357-
client.ConnectionSettings.ConnectionPool
358-
.Should().BeOfType<StickySniffingConnectionPool>();
359251
----
360252

0 commit comments

Comments
 (0)