Skip to content

Commit ee3752e

Browse files
committed
Fix initial randomization of nodes (#4112)
This commit fixes the initial randomization of nodes in a StaticConnectionPool. Instead of calling the protected ctor, the initialization logic has been pulled out into a separate method that is now called from the ctor that accepts a randomize parameter. Fixes #4055
1 parent 61b9844 commit ee3752e

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

src/Elasticsearch.Net/ConnectionPool/StaticConnectionPool.cs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,38 @@ public StaticConnectionPool(IEnumerable<Uri> uris, bool randomize = true, IDateT
1515
: this(uris.Select(uri => new Node(uri)), randomize, dateTimeProvider) { }
1616

1717
public StaticConnectionPool(IEnumerable<Node> nodes, bool randomize = true, IDateTimeProvider dateTimeProvider = null)
18-
: this(nodes, null, dateTimeProvider) => Randomize = randomize;
18+
{
19+
nodes.ThrowIfEmpty(nameof(nodes));
20+
Randomize = randomize;
21+
Initialize(nodes, dateTimeProvider);
22+
}
1923

2024
//this constructor is protected because nodeScorer only makes sense on subclasses that support reseeding
2125
//otherwise just manually sort `nodes` before instantiating.
2226
protected StaticConnectionPool(IEnumerable<Node> nodes, Func<Node, float> nodeScorer, IDateTimeProvider dateTimeProvider = null)
2327
{
2428
nodes.ThrowIfEmpty(nameof(nodes));
25-
DateTimeProvider = dateTimeProvider ?? Net.DateTimeProvider.Default;
29+
_nodeScorer = nodeScorer;
30+
Initialize(nodes, dateTimeProvider);
31+
}
2632

27-
var nn = nodes.ToList();
28-
var uris = nn.Select(n => n.Uri).ToList();
29-
if (uris.Select(u => u.Scheme).Distinct().Count() > 1)
30-
throw new ArgumentException("Trying to instantiate a connection pool with mixed URI Schemes");
33+
private void Initialize(IEnumerable<Node> nodes, IDateTimeProvider dateTimeProvider)
34+
{
35+
DateTimeProvider = dateTimeProvider ?? Net.DateTimeProvider.Default;
3136

32-
UsingSsl = uris.Any(uri => uri.Scheme == "https");
37+
string scheme = null;
38+
foreach (var node in nodes)
39+
{
40+
if (scheme == null)
41+
{
42+
scheme = node.Uri.Scheme;
43+
UsingSsl = scheme == "https";
44+
}
45+
else if (scheme != node.Uri.Scheme)
46+
throw new ArgumentException("Trying to instantiate a connection pool with mixed URI Schemes");
47+
}
3348

34-
_nodeScorer = nodeScorer;
35-
InternalNodes = SortNodes(nn)
49+
InternalNodes = SortNodes(nodes)
3650
.DistinctBy(n => n.Uri)
3751
.ToList();
3852
LastUpdate = DateTimeProvider.Now();
@@ -57,7 +71,7 @@ protected StaticConnectionPool(IEnumerable<Node> nodes, Func<Node, float> nodeSc
5771
public virtual bool SupportsReseeding => false;
5872

5973
/// <inheritdoc />
60-
public bool UsingSsl { get; }
74+
public bool UsingSsl { get; private set; }
6175

6276
protected List<Node> AliveNodes
6377
{
@@ -70,7 +84,7 @@ protected List<Node> AliveNodes
7084
}
7185
}
7286

73-
protected IDateTimeProvider DateTimeProvider { get; }
87+
protected IDateTimeProvider DateTimeProvider { get; private set; }
7488

7589
protected List<Node> InternalNodes { get; set; }
7690
protected Random Random { get; } = new Random();

src/Tests/Tests/ClientConcepts/ConnectionPooling/BuildingBlocks/ConnectionPooling.doc.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,30 @@ [U] public void Static()
214214
}
215215
}
216216

217+
// hide
218+
[U] public void RandomizedInitialNodes()
219+
{
220+
StaticConnectionPool CreatStaticConnectionPool()
221+
{
222+
var uris = new[]
223+
{
224+
new Uri("https://10.0.0.1:9200/"),
225+
new Uri("https://10.0.0.2:9200/"),
226+
new Uri("https://10.0.0.3:9200/")
227+
};
228+
229+
var staticConnectionPool = new StaticConnectionPool(uris);
230+
return staticConnectionPool;
231+
}
232+
233+
// assertion works on the probability of seeing a Uri other than https://10.0.0.1:9200/
234+
// as the first value over 50 runs, when randomized.
235+
Enumerable.Repeat(CreatStaticConnectionPool().CreateView().First().Uri.ToString(), 50)
236+
.All(uri => uri == "https://10.0.0.1:9200/")
237+
.Should()
238+
.BeFalse();
239+
}
240+
217241
/**[[sniffing-connection-pool]]
218242
* ==== SniffingConnectionPool
219243
*

0 commit comments

Comments
 (0)