Skip to content

Commit 4647ed9

Browse files
author
rstam
committed
Fixed CSHARP-370 and CSHARP-411. The C# driver now detects whether replica set members are added or removed while it is connected. CSHARP-370 required some changes to the timing of DNS lookups that ended up fixing CSHARP-411 also.
1 parent e0634a9 commit 4647ed9

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

Driver/Core/MongoServer.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,28 @@ internal void RemoveInstance(MongoServerInstance instance)
12331233
}
12341234
}
12351235

1236+
internal void VerifyInstances(List<MongoServerAddress> instanceAddresses)
1237+
{
1238+
lock (_stateLock)
1239+
{
1240+
foreach (var instance in _instances)
1241+
{
1242+
if (!instanceAddresses.Contains(instance.Address))
1243+
{
1244+
RemoveInstance(instance);
1245+
}
1246+
}
1247+
foreach (var address in instanceAddresses)
1248+
{
1249+
if (!_instances.Any(instance => instance.Address == address))
1250+
{
1251+
var instance = new MongoServerInstance(this, address);
1252+
AddInstance(instance);
1253+
}
1254+
}
1255+
}
1256+
}
1257+
12361258
// private methods
12371259
private void InstanceStateChanged(object sender, object args)
12381260
{

Driver/Core/MongoServerInstance.cs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,17 @@ public MongoConnectionPool ConnectionPool
121121
/// </summary>
122122
public IPEndPoint EndPoint
123123
{
124-
get { return _endPoint; }
124+
get {
125+
// use a lock free algorithm because DNS lookups are rare and concurrent lookups are tolerable
126+
// the intermediate variable is important to avoid race conditions
127+
var endPoint = _endPoint;
128+
if (endPoint == null)
129+
{
130+
endPoint = _address.ToIPEndPoint(_server.Settings.AddressFamily);
131+
_endPoint = endPoint;
132+
}
133+
return endPoint;
134+
}
125135
}
126136

127137
/// <summary>
@@ -307,8 +317,6 @@ internal void Connect(bool slaveOk)
307317
_connectException = null;
308318
try
309319
{
310-
_endPoint = _address.ToIPEndPoint(_server.Settings.AddressFamily);
311-
312320
try
313321
{
314322
var connection = _connectionPool.AcquireConnection(null);
@@ -454,6 +462,38 @@ internal void VerifyState(MongoConnection connection)
454462
_maxMessageLength = maxMessageLength;
455463
_buildInfo = buildInfo;
456464
this.SetState(MongoServerState.Connected, isPrimary, isSecondary, isPassive, isArbiter);
465+
466+
// if this is the primary of a replica set check to see if any instances have been added or removed
467+
if (isPrimary && _server.Settings.ConnectionMode == ConnectionMode.ReplicaSet)
468+
{
469+
var instanceAddresses = new List<MongoServerAddress>();
470+
if (isMasterResult.Response.Contains("hosts"))
471+
{
472+
foreach (var hostName in isMasterResult.Response["hosts"].AsBsonArray)
473+
{
474+
var address = MongoServerAddress.Parse(hostName.AsString);
475+
instanceAddresses.Add(address);
476+
}
477+
}
478+
if (isMasterResult.Response.Contains("passives"))
479+
{
480+
foreach (var hostName in isMasterResult.Response["passives"].AsBsonArray)
481+
{
482+
var address = MongoServerAddress.Parse(hostName.AsString);
483+
instanceAddresses.Add(address);
484+
}
485+
}
486+
if (isMasterResult.Response.Contains("arbiters"))
487+
{
488+
foreach (var hostName in isMasterResult.Response["arbiters"].AsBsonArray)
489+
{
490+
var address = MongoServerAddress.Parse(hostName.AsString);
491+
instanceAddresses.Add(address);
492+
}
493+
}
494+
_server.VerifyInstances(instanceAddresses);
495+
}
496+
457497
ok = true;
458498
}
459499
finally

0 commit comments

Comments
 (0)