Exemple #1
0
        private void ProcessServerDescriptionChanged(ServerDescriptionChangedEventArgs args)
        {
            var newServerDescription  = args.NewServerDescription;
            var newClusterDescription = Description;

            if (!_servers.Any(x => EndPointHelper.Equals(x.EndPoint, newServerDescription.EndPoint)))
            {
                return;
            }

            var newServers = new List <IClusterableServer>();

            if (newServerDescription.State == ServerState.Disconnected)
            {
                newClusterDescription = newClusterDescription.WithServerDescription(newServerDescription);
            }
            else
            {
                if (IsServerValidForCluster(newClusterDescription.Type, Settings.ConnectionMode, newServerDescription.Type))
                {
                    if (newClusterDescription.Type == ClusterType.Unknown)
                    {
                        newClusterDescription = newClusterDescription.WithType(newServerDescription.Type.ToClusterType());
                    }

                    switch (newClusterDescription.Type)
                    {
                    case ClusterType.ReplicaSet:
                        newClusterDescription = ProcessReplicaSetChange(newClusterDescription, args, newServers);
                        break;

                    case ClusterType.Sharded:
                        newClusterDescription = ProcessShardedChange(newClusterDescription, args);
                        break;

                    default:
                        throw new MongoInternalException("Unexpected cluster type.");
                    }
                }
                else
                {
                    newClusterDescription = newClusterDescription.WithoutServerDescription(newServerDescription.EndPoint);
                }
            }

            UpdateClusterDescription(newClusterDescription);

            foreach (var server in newServers)
            {
                server.Initialize();
            }
        }
Exemple #2
0
        private void ProcessServerDescriptionChanged(ServerDescriptionChangedEventArgs args)
        {
            var currentClusterDescription = Description;
            var currentServerDescription  = args.OldServerDescription;
            var newServerDescription      = args.NewServerDescription;

            var currentServer = _servers.SingleOrDefault(x => x.EndPoint.Equals(newServerDescription.EndPoint));

            if (currentServer == null)
            {
                return;
            }

            ClusterDescription newClusterDescription;

            if (newServerDescription.State == ServerState.Disconnected)
            {
                newClusterDescription = currentClusterDescription.WithServerDescription(args.NewServerDescription);
            }
            else if (newServerDescription.Type == ServerType.Standalone)
            {
                newClusterDescription = currentClusterDescription.WithoutServerDescription(args.NewServerDescription.EndPoint);
            }
            else
            {
                if (currentClusterDescription.Type == ClusterType.Unknown)
                {
                    currentClusterDescription = currentClusterDescription.WithType(args.NewServerDescription.Type.ToClusterType());
                }

                switch (currentClusterDescription.Type)
                {
                case ClusterType.ReplicaSet:
                    newClusterDescription = ProcessReplicaSetChange(currentClusterDescription, args);
                    break;

                case ClusterType.Sharded:
                    newClusterDescription = ProcessShardedChange(currentClusterDescription, args);
                    break;

                case ClusterType.Standalone:
                    throw new MongoInternalException("MultiServerCluster does not support a standalone state.");

                default:
                    newClusterDescription = currentClusterDescription.WithServerDescription(newServerDescription);
                    break;
                }
            }

            UpdateClusterDescription(newClusterDescription);
        }
        private void ServerDescriptionChanged(object sender, ServerDescriptionChangedEventArgs args)
        {
            var newServerDescription  = args.NewServerDescription;
            var newClusterDescription = Description;

            if (_replicaSetName != null)
            {
                var replicaSetConfig = newServerDescription.ReplicaSetConfig;
                if (replicaSetConfig == null || replicaSetConfig.Name != _replicaSetName)
                {
                    // if the replica set name does not match then the ServerType in the ServerDescription MUST be replaced with Unknown
                    newServerDescription = newServerDescription.With(type: ServerType.Unknown);
                }
            }

            if (newServerDescription.State == ServerState.Disconnected)
            {
                newClusterDescription = newClusterDescription.WithServerDescription(newServerDescription);
            }
            else
            {
                if (IsServerValidForCluster(newClusterDescription.Type, Settings.ConnectionMode, newServerDescription.Type))
                {
                    if (newClusterDescription.Type == ClusterType.Unknown)
                    {
                        newClusterDescription = newClusterDescription.WithType(newServerDescription.Type.ToClusterType());
                    }

                    newClusterDescription = newClusterDescription.WithServerDescription(newServerDescription);
                }
                else
                {
                    newClusterDescription = newClusterDescription.WithoutServerDescription(newServerDescription.EndPoint);
                }
            }

            var shouldClusterDescriptionChangedEventBePublished = !args.OldServerDescription.SdamEquals(args.NewServerDescription);

            UpdateClusterDescription(newClusterDescription, shouldClusterDescriptionChangedEventBePublished);
        }
Exemple #4
0
        private ClusterDescription ProcessShardedChange(ClusterDescription clusterDescription, ServerDescriptionChangedEventArgs args)
        {
            if (args.NewServerDescription.Type != ServerType.ShardRouter)
            {
                return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, "Server is not a shard router."));
            }

            return(clusterDescription.WithServerDescription(args.NewServerDescription));
        }
Exemple #5
0
        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);
        }
Exemple #6
0
 private void ServerDescriptionChangedHandler(object sender, ServerDescriptionChangedEventArgs args)
 {
     _serverDescriptionChangedQueue.Enqueue(args);
 }
Exemple #7
0
        private ClusterDescription ProcessStandaloneChange(ClusterDescription clusterDescription, ServerDescriptionChangedEventArgs args)
        {
            if (args.NewServerDescription.Type != ServerType.Unknown)
            {
                if (args.NewServerDescription.Type == ServerType.Standalone)
                {
                    foreach (var endPoint in clusterDescription.Servers.Select(s => s.EndPoint).ToList())
                    {
                        if (!EndPointHelper.Equals(endPoint, args.NewServerDescription.EndPoint))
                        {
                            clusterDescription = RemoveServer(clusterDescription, endPoint, "Removing all other end points once a standalone is discovered.");
                        }
                    }
                }
                else
                {
                    return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, "Server is not a standalone server."));
                }
            }

            return(clusterDescription.WithServerDescription(args.NewServerDescription));
        }
Exemple #8
0
        private void ProcessServerDescriptionChanged(ServerDescriptionChangedEventArgs args)
        {
            var newServers = new List <IClusterableServer>();

            lock (_updateClusterDescriptionLock)
            {
                var newServerDescription  = args.NewServerDescription;
                var newClusterDescription = Description;

                if (!_servers.Any(x => EndPointHelper.Equals(x.EndPoint, newServerDescription.EndPoint)))
                {
                    return;
                }

                if (newServerDescription.State == ServerState.Disconnected)
                {
                    newClusterDescription = newClusterDescription.WithServerDescription(newServerDescription);
                }
                else
                {
                    if (IsServerValidForCluster(newClusterDescription.Type, Settings, newServerDescription.Type))
                    {
                        if (newClusterDescription.Type == ClusterType.Unknown)
                        {
                            if (newServerDescription.Type != ServerType.ReplicaSetGhost)
                            {
                                // Unknown cluster description with ServerType.ReplicaSetGhost should be untouched
                                newClusterDescription = newClusterDescription.WithType(newServerDescription.Type.ToClusterType());
                            }
                        }

                        switch (newClusterDescription.Type)
                        {
                        case ClusterType.Standalone:
                            newClusterDescription = ProcessStandaloneChange(newClusterDescription, args);
                            break;

                        case ClusterType.ReplicaSet:
                        case ClusterType.Unknown when newServerDescription.Type == ServerType.ReplicaSetGhost:     // update serverDescription in clusterDescription
                            newClusterDescription = ProcessReplicaSetChange(newClusterDescription, args, newServers);
                            break;

                        case ClusterType.Sharded:
                            newClusterDescription = ProcessShardedChange(newClusterDescription, args);
                            break;

                        default:
                            throw new MongoInternalException("Unexpected cluster type.");
                        }
                    }
                    else
                    {
                        var reason = $"The server {newServerDescription.EndPoint} with type {newServerDescription.Type} is not valid for cluster type {newClusterDescription.Type}.";
                        newClusterDescription = RemoveServer(newClusterDescription, newServerDescription.EndPoint, reason);
                    }
                }

                var shouldClusterDescriptionChangedEventBePublished = !args.OldServerDescription.SdamEquals(args.NewServerDescription);
                UpdateClusterDescription(newClusterDescription, shouldClusterDescriptionChangedEventBePublished);
            }

            foreach (var server in newServers)
            {
                server.Initialize();
            }
        }
        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);
        }
Exemple #10
0
        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);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
 private ClusterDescription ProcessStandaloneChange(ClusterDescription clusterDescription, ServerDescriptionChangedEventArgs args)
 {
     if (Settings.EndPoints.Count > 1)
     {
         return(RemoveServer(clusterDescription, args.NewServerDescription.EndPoint, "Cluster was provided with multiple endpoints, one of which is a standalone."));
     }
     if (args.NewServerDescription.Type != ServerType.Standalone)
     {
         return(clusterDescription.WithServerDescription(
                    new ServerDescription(args.NewServerDescription.ServerId, args.NewServerDescription.EndPoint)));
     }
     else
     {
         return(clusterDescription.WithServerDescription(args.NewServerDescription));
     }
 }