Skip to content

Commit 7fbf732

Browse files
craiggwilsonrstam
authored andcommitted
CSHARP-1526: use setVersion and electionIds for mitigating race conditions between protocols.
1 parent 1a7414e commit 7fbf732

25 files changed

+1493
-121
lines changed

src/MongoDB.Driver.Core.Tests/Core/Clusters/MultiServerClusterTests.cs

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ public void Should_remove_server_from_the_seed_list_that_is_not_in_the_hosts_lis
394394
}
395395

396396
[Test]
397-
public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_and_current_election_id_is_null()
397+
public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_and_current_set_version_and_election_id_are_null()
398398
{
399399
_settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
400400

@@ -418,7 +418,7 @@ public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_and_c
418418
}
419419

420420
[Test]
421-
public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_an_election_id_and_current_id_is_null()
421+
public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_an_election_id_and_current_set_version_and_election_id_are_null()
422422
{
423423
_settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
424424

@@ -427,7 +427,7 @@ public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_
427427
_capturedEvents.Clear();
428428

429429
PublishDescription(_firstEndPoint, ServerType.ReplicaSetPrimary);
430-
PublishDescription(_secondEndPoint, ServerType.ReplicaSetPrimary, electionId: new ElectionId(ObjectId.GenerateNewId()));
430+
PublishDescription(_secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.GenerateNewId()));
431431

432432
var description = subject.Description;
433433
description.Servers.Should().BeEquivalentTo(
@@ -442,16 +442,16 @@ public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_
442442
}
443443

444444
[Test]
445-
public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_a_higher_election_id()
445+
public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_a_higher_set_version()
446446
{
447447
_settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
448448

449449
var subject = CreateSubject();
450450
subject.Initialize();
451451
_capturedEvents.Clear();
452452

453-
PublishDescription(_firstEndPoint, ServerType.ReplicaSetPrimary, electionId: new ElectionId(ObjectId.Empty));
454-
PublishDescription(_secondEndPoint, ServerType.ReplicaSetPrimary, electionId: new ElectionId(ObjectId.GenerateNewId()));
453+
PublishDescription(_firstEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.Empty));
454+
PublishDescription(_secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 2, electionId: new ElectionId(ObjectId.Empty));
455455

456456
var description = subject.Description;
457457
description.Servers.Should().BeEquivalentTo(
@@ -466,16 +466,64 @@ public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_
466466
}
467467

468468
[Test]
469-
public void Should_invalidate_new_primary_when_it_shows_up_with_a_lesser_election_id()
469+
public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_the_same_set_version_and_a_higher_election_id()
470470
{
471471
_settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
472472

473473
var subject = CreateSubject();
474474
subject.Initialize();
475475
_capturedEvents.Clear();
476476

477-
PublishDescription(_firstEndPoint, ServerType.ReplicaSetPrimary, electionId: new ElectionId(ObjectId.GenerateNewId()));
478-
PublishDescription(_secondEndPoint, ServerType.ReplicaSetPrimary, electionId: new ElectionId(ObjectId.Empty));
477+
PublishDescription(_firstEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.Empty));
478+
PublishDescription(_secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.GenerateNewId()));
479+
480+
var description = subject.Description;
481+
description.Servers.Should().BeEquivalentTo(
482+
new[] { GetDisconnectedDescription(_firstEndPoint) }
483+
.Concat(GetDescriptions(_secondEndPoint, _thirdEndPoint)));
484+
485+
_serverFactory.GetServer(_firstEndPoint).Received().Invalidate();
486+
487+
_capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
488+
_capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
489+
_capturedEvents.Any().Should().BeFalse();
490+
}
491+
492+
[Test]
493+
public void Should_invalidate_new_primary_when_it_shows_up_with_a_lesser_set_version()
494+
{
495+
_settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
496+
497+
var subject = CreateSubject();
498+
subject.Initialize();
499+
_capturedEvents.Clear();
500+
501+
PublishDescription(_firstEndPoint, ServerType.ReplicaSetPrimary, setVersion: 2, electionId: new ElectionId(ObjectId.Empty));
502+
PublishDescription(_secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.GenerateNewId()));
503+
504+
var description = subject.Description;
505+
description.Servers.Should().BeEquivalentTo(
506+
new[] { GetDisconnectedDescription(_secondEndPoint) }
507+
.Concat(GetDescriptions(_firstEndPoint, _thirdEndPoint)));
508+
509+
_serverFactory.GetServer(_secondEndPoint).Received().Invalidate();
510+
511+
_capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
512+
_capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
513+
_capturedEvents.Any().Should().BeFalse();
514+
}
515+
516+
[Test]
517+
public void Should_invalidate_new_primary_when_it_shows_up_with_the_same_set_version_and_a_lesser_election_id()
518+
{
519+
_settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
520+
521+
var subject = CreateSubject();
522+
subject.Initialize();
523+
_capturedEvents.Clear();
524+
525+
PublishDescription(_firstEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.GenerateNewId()));
526+
PublishDescription(_secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.Empty));
479527

480528
var description = subject.Description;
481529
description.Servers.Should().BeEquivalentTo(
@@ -617,15 +665,15 @@ private void PublishDisconnectedDescription(EndPoint endPoint)
617665
_serverFactory.PublishDescription(description);
618666
}
619667

620-
private void PublishDescription(EndPoint endPoint, ServerType serverType, IEnumerable<EndPoint> hosts = null, string setName = null, EndPoint primary = null, ElectionId electionId = null, EndPoint canonicalEndPoint = null)
668+
private void PublishDescription(EndPoint endPoint, ServerType serverType, IEnumerable<EndPoint> hosts = null, string setName = null, EndPoint primary = null, ElectionId electionId = null, EndPoint canonicalEndPoint = null, int? setVersion = null)
621669
{
622670
var current = _serverFactory.GetServerDescription(endPoint);
623671

624672
var config = new ReplicaSetConfig(
625673
hosts ?? new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint },
626674
setName ?? "test",
627675
primary,
628-
null);
676+
setVersion);
629677

630678
var description = current.With(
631679
averageRoundTripTime: TimeSpan.FromMilliseconds(10),

0 commit comments

Comments
 (0)