private ClusterDescription ProcessReplicaSetChange(ClusterDescription clusterDescription, ServerDescriptionChangedEventArgs args) { if (!args.NewServerDescription.Type.IsReplicaSetMember()) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, string.Format("Server is a {0}, not a replica set member.", args.NewServerDescription.Type))); } if (args.NewServerDescription.Type == ServerType.ReplicaSetGhost) { return(clusterDescription.WithServerDescription(args.NewServerDescription)); } if (_replicaSetName == null) { _replicaSetName = args.NewServerDescription.ReplicaSetConfig.Name; } if (_replicaSetName != args.NewServerDescription.ReplicaSetConfig.Name) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, string.Format("Server was a member of the '{0}' replica set, but should be '{1}'.", args.NewServerDescription.ReplicaSetConfig.Name, _replicaSetName))); } clusterDescription = clusterDescription.WithServerDescription(args.NewServerDescription); clusterDescription = EnsureServers(clusterDescription, args.NewServerDescription); if (args.NewServerDescription.Type == ServerType.ReplicaSetPrimary && args.OldServerDescription.Type != ServerType.ReplicaSetPrimary) { var currentPrimaryEndPoints = clusterDescription.Servers .Where(x => x.Type == ServerType.ReplicaSetPrimary) .Where(x => !EndPointHelper.Equals(x.EndPoint, args.NewServerDescription.EndPoint)) .Select(x => x.EndPoint) .ToList(); if (currentPrimaryEndPoints.Count > 0) { lock (_serversLock) { var currentPrimaries = _servers.Where(x => EndPointHelper.Contains(currentPrimaryEndPoints, x.EndPoint)); foreach (var currentPrimary in currentPrimaries) { // kick off the server to invalidate itself currentPrimary.Invalidate(); // set it to disconnected in the cluster clusterDescription = clusterDescription.WithServerDescription( new ServerDescription(currentPrimary.ServerId, currentPrimary.EndPoint)); } } } } return(clusterDescription); }
private void OnClusterDescriptionChanged(object sender, EventArgs args) { var clusterDescription = _cluster.Description; var endPoints = clusterDescription.Servers.Select(s => s.EndPoint).ToList(); lock (_serverLock) { _serverInstances.RemoveAll(instance => !EndPointHelper.Contains(endPoints, instance.EndPoint)); var newEndPoints = endPoints.Where(endPoint => !_serverInstances.Any(i => i.EndPoint.Equals(endPoint))).ToList(); if (newEndPoints.Count > 0) { _serverInstances.AddRange(newEndPoints.Select(endPoint => new MongoServerInstance(_settings, ToMongoServerAddress(endPoint), _cluster, endPoint))); _serverInstances.Sort(ServerInstanceAddressComparer.Instance); } } }
private ClusterDescription EnsureServers(ClusterDescription clusterDescription, ServerDescription serverDescription, List <IClusterableServer> newServers) { if (serverDescription.Type == ServerType.ReplicaSetPrimary || !clusterDescription.Servers.Any(x => x.Type == ServerType.ReplicaSetPrimary)) { foreach (var endPoint in serverDescription.ReplicaSetConfig.Members) { clusterDescription = EnsureServer(clusterDescription, endPoint, newServers); } } if (serverDescription.Type == ServerType.ReplicaSetPrimary) { var requiredEndPoints = serverDescription.ReplicaSetConfig.Members; var extraEndPoints = clusterDescription.Servers.Where(x => !EndPointHelper.Contains(requiredEndPoints, x.EndPoint)).Select(x => x.EndPoint); foreach (var endPoint in extraEndPoints) { clusterDescription = RemoveServer(clusterDescription, endPoint, "Server is not in the host list of the primary."); } } return(clusterDescription); }
private ClusterDescription ProcessReplicaSetChange(ClusterDescription clusterDescription, ServerDescriptionChangedEventArgs args, List <IClusterableServer> newServers) { if (!args.NewServerDescription.Type.IsReplicaSetMember()) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, string.Format("Server is a {0}, not a replica set member.", args.NewServerDescription.Type))); } if (args.NewServerDescription.Type == ServerType.ReplicaSetGhost) { return(clusterDescription.WithServerDescription(args.NewServerDescription)); } if (_replicaSetName == null) { _replicaSetName = args.NewServerDescription.ReplicaSetConfig.Name; } if (_replicaSetName != args.NewServerDescription.ReplicaSetConfig.Name) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, string.Format("Server was a member of the '{0}' replica set, but should be '{1}'.", args.NewServerDescription.ReplicaSetConfig.Name, _replicaSetName))); } clusterDescription = clusterDescription.WithServerDescription(args.NewServerDescription); clusterDescription = EnsureServers(clusterDescription, args.NewServerDescription, newServers); if (args.NewServerDescription.CanonicalEndPoint != null && !EndPointHelper.Equals(args.NewServerDescription.CanonicalEndPoint, args.NewServerDescription.EndPoint)) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, "CanonicalEndPoint is different than seed list EndPoint.")); } if (args.NewServerDescription.Type == ServerType.ReplicaSetPrimary) { if (args.NewServerDescription.ReplicaSetConfig.Version != null) { bool isCurrentPrimaryStale = true; if (_maxElectionInfo != null) { isCurrentPrimaryStale = _maxElectionInfo.IsStale(args.NewServerDescription.ReplicaSetConfig.Version.Value, args.NewServerDescription.ElectionId); var isReportedPrimaryStale = _maxElectionInfo.IsFresher( args.NewServerDescription.ReplicaSetConfig.Version.Value, args.NewServerDescription.ElectionId); if (isReportedPrimaryStale && args.NewServerDescription.ElectionId != null) { // we only invalidate the "newly" reported stale primary if electionId was used. lock (_serversLock) { var server = _servers.SingleOrDefault(x => EndPointHelper.Equals(args.NewServerDescription.EndPoint, x.EndPoint)); server.Invalidate(); _sdamInformationEventHandler?.Invoke(new SdamInformationEvent(() => string.Format( @"Invalidating server: Setting ServerType to ""Unknown"" for {0} because it " + @"claimed to be the replica set primary for replica set ""{1}"" but sent a " + @"(setVersion, electionId) tuple of ({2}, {3}) that was less than than the " + @"largest tuple seen, (maxSetVersion, maxElectionId), of ({4}, {5}).", args.NewServerDescription.EndPoint, args.NewServerDescription.ReplicaSetConfig.Name, args.NewServerDescription.ReplicaSetConfig.Version, args.NewServerDescription.ElectionId, _maxElectionInfo.SetVersion, _maxElectionInfo.ElectionId))); return(clusterDescription.WithServerDescription( new ServerDescription(server.ServerId, server.EndPoint))); } } } if (isCurrentPrimaryStale) { if (_maxElectionInfo == null) { _sdamInformationEventHandler?.Invoke(new SdamInformationEvent(() => string.Format( @"Initializing (maxSetVersion, maxElectionId): Saving tuple " + @"(setVersion, electionId) of ({0}, {1}) as (maxSetVersion, maxElectionId) for " + @"replica set ""{2}"" because replica set primary {3} sent ({0}, {1}), the first " + @"(setVersion, electionId) tuple ever seen for replica set ""{4}"".", args.NewServerDescription.ReplicaSetConfig.Version, args.NewServerDescription.ElectionId, args.NewServerDescription.ReplicaSetConfig.Name, args.NewServerDescription.EndPoint, args.NewServerDescription.ReplicaSetConfig.Name))); } else { if (_maxElectionInfo.SetVersion < args.NewServerDescription.ReplicaSetConfig.Version.Value) { _sdamInformationEventHandler?.Invoke(new SdamInformationEvent(() => string.Format( @"Updating stale setVersion: Updating the current " + @"(maxSetVersion, maxElectionId) tuple from ({0}, {1}) to ({2}, {3}) for " + @"replica set ""{4}"" because replica set primary {5} sent ({6}, {7})—a larger " + @"(setVersion, electionId) tuple then the saved tuple, ({0}, {1}).", _maxElectionInfo.SetVersion, _maxElectionInfo.ElectionId, args.NewServerDescription.ReplicaSetConfig.Version, args.NewServerDescription.ElectionId, args.NewServerDescription.ReplicaSetConfig.Name, args.NewServerDescription.EndPoint, args.NewServerDescription.ReplicaSetConfig.Version, args.NewServerDescription.ElectionId))); } else // current primary is stale & setVersion is not stale ⇒ the electionId must be stale { _sdamInformationEventHandler?.Invoke(new SdamInformationEvent(() => string.Format( @"Updating stale electionId: Updating the current " + @"(maxSetVersion, maxElectionId) tuple from ({0}, {1}) to ({2}, {3}) for " + @"replica set ""{4}"" because replica set primary {5} sent ({6}, {7})—" + @"a larger (setVersion, electionId) tuple than the saved tuple, ({0}, {1}).", _maxElectionInfo.SetVersion, _maxElectionInfo.ElectionId, args.NewServerDescription.ReplicaSetConfig.Version, args.NewServerDescription.ElectionId, args.NewServerDescription.ReplicaSetConfig.Name, args.NewServerDescription.EndPoint, args.NewServerDescription.ReplicaSetConfig.Version, args.NewServerDescription.ElectionId))); } } _maxElectionInfo = new ElectionInfo( args.NewServerDescription.ReplicaSetConfig.Version.Value, args.NewServerDescription.ElectionId); } } var currentPrimaryEndPoints = clusterDescription.Servers .Where(x => x.Type == ServerType.ReplicaSetPrimary) .Where(x => !EndPointHelper.Equals(x.EndPoint, args.NewServerDescription.EndPoint)) .Select(x => x.EndPoint) .ToList(); if (currentPrimaryEndPoints.Count > 0) { lock (_serversLock) { var currentPrimaries = _servers.Where(x => EndPointHelper.Contains(currentPrimaryEndPoints, x.EndPoint)); foreach (var currentPrimary in currentPrimaries) { // kick off the server to invalidate itself currentPrimary.Invalidate(); // set it to disconnected in the cluster clusterDescription = clusterDescription.WithServerDescription( new ServerDescription(currentPrimary.ServerId, currentPrimary.EndPoint)); } } } } return(clusterDescription); }
private ClusterDescription ProcessReplicaSetChange(ClusterDescription clusterDescription, ServerDescriptionChangedEventArgs args, List <IClusterableServer> newServers) { if (!args.NewServerDescription.Type.IsReplicaSetMember()) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, string.Format("Server is a {0}, not a replica set member.", args.NewServerDescription.Type))); } if (args.NewServerDescription.Type == ServerType.ReplicaSetGhost) { return(clusterDescription.WithServerDescription(args.NewServerDescription)); } if (_replicaSetName == null) { _replicaSetName = args.NewServerDescription.ReplicaSetConfig.Name; } if (_replicaSetName != args.NewServerDescription.ReplicaSetConfig.Name) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, string.Format("Server was a member of the '{0}' replica set, but should be '{1}'.", args.NewServerDescription.ReplicaSetConfig.Name, _replicaSetName))); } clusterDescription = clusterDescription.WithServerDescription(args.NewServerDescription); clusterDescription = EnsureServers(clusterDescription, args.NewServerDescription, newServers); if (args.NewServerDescription.CanonicalEndPoint != null && !EndPointHelper.Equals(args.NewServerDescription.CanonicalEndPoint, args.NewServerDescription.EndPoint)) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, "CanonicalEndPoint is different than seed list EndPoint.")); } if (args.NewServerDescription.Type == ServerType.ReplicaSetPrimary) { if (args.NewServerDescription.ReplicaSetConfig.Version != null) { bool isCurrentPrimaryStale = true; if (_maxElectionInfo != null) { isCurrentPrimaryStale = _maxElectionInfo.IsStale(args.NewServerDescription.ReplicaSetConfig.Version.Value, args.NewServerDescription.ElectionId); var isReportedPrimaryStale = !isCurrentPrimaryStale; if (isReportedPrimaryStale && args.NewServerDescription.ElectionId != null) { // we only invalidate the "newly" reported stale primary if electionId was used. lock (_serversLock) { var server = _servers.SingleOrDefault(x => EndPointHelper.Equals(args.NewServerDescription.EndPoint, x.EndPoint)); server.Invalidate(); return(clusterDescription.WithServerDescription( new ServerDescription(server.ServerId, server.EndPoint))); } } } if (isCurrentPrimaryStale) { _maxElectionInfo = new ElectionInfo( args.NewServerDescription.ReplicaSetConfig.Version.Value, args.NewServerDescription.ElectionId); } } var currentPrimaryEndPoints = clusterDescription.Servers .Where(x => x.Type == ServerType.ReplicaSetPrimary) .Where(x => !EndPointHelper.Equals(x.EndPoint, args.NewServerDescription.EndPoint)) .Select(x => x.EndPoint) .ToList(); if (currentPrimaryEndPoints.Count > 0) { lock (_serversLock) { var currentPrimaries = _servers.Where(x => EndPointHelper.Contains(currentPrimaryEndPoints, x.EndPoint)); foreach (var currentPrimary in currentPrimaries) { // kick off the server to invalidate itself currentPrimary.Invalidate(); // set it to disconnected in the cluster clusterDescription = clusterDescription.WithServerDescription( new ServerDescription(currentPrimary.ServerId, currentPrimary.EndPoint)); } } } } return(clusterDescription); }
private ClusterDescription ProcessReplicaSetChange(ClusterDescription clusterDescription, ServerDescriptionChangedEventArgs args) { if (!args.NewServerDescription.Type.IsReplicaSetMember()) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, string.Format("Server is a {0}, not a replica set member.", args.NewServerDescription.Type))); } if (args.NewServerDescription.Type == ServerType.ReplicaSetGhost) { return(clusterDescription.WithServerDescription(args.NewServerDescription)); } if (_replicaSetName == null) { _replicaSetName = args.NewServerDescription.ReplicaSetConfig.Name; } if (_replicaSetName != args.NewServerDescription.ReplicaSetConfig.Name) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, string.Format("Server was a member of the '{0}' replica set, but should be '{1}'.", args.NewServerDescription.ReplicaSetConfig.Name, _replicaSetName))); } clusterDescription = clusterDescription.WithServerDescription(args.NewServerDescription); clusterDescription = EnsureServers(clusterDescription, args.NewServerDescription); if (args.NewServerDescription.CanonicalEndPoint != null && !EndPointHelper.Equals(args.NewServerDescription.CanonicalEndPoint, args.NewServerDescription.EndPoint)) { return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, "CanonicalEndPoint is different than seed list EndPoint.")); } if (args.NewServerDescription.Type == ServerType.ReplicaSetPrimary) { if (args.NewServerDescription.ElectionId != null) { if (_maxElectionId != null && _maxElectionId.CompareTo(args.NewServerDescription.ElectionId) > 0) { // ignore this change because we've already seen this election id lock (_serversLock) { var server = _servers.SingleOrDefault(x => EndPointHelper.Equals(args.NewServerDescription.EndPoint, x.EndPoint)); server.Invalidate(); return(clusterDescription.WithServerDescription( new ServerDescription(server.ServerId, server.EndPoint))); } } _maxElectionId = args.NewServerDescription.ElectionId; } var currentPrimaryEndPoints = clusterDescription.Servers .Where(x => x.Type == ServerType.ReplicaSetPrimary) .Where(x => !EndPointHelper.Equals(x.EndPoint, args.NewServerDescription.EndPoint)) .Select(x => x.EndPoint) .ToList(); if (currentPrimaryEndPoints.Count > 0) { lock (_serversLock) { var currentPrimaries = _servers.Where(x => EndPointHelper.Contains(currentPrimaryEndPoints, x.EndPoint)); foreach (var currentPrimary in currentPrimaries) { // kick off the server to invalidate itself currentPrimary.Invalidate(); // set it to disconnected in the cluster clusterDescription = clusterDescription.WithServerDescription( new ServerDescription(currentPrimary.ServerId, currentPrimary.EndPoint)); } } } } return(clusterDescription); }