// private methods private void LookupServerInformation(MongoConnection connection) { IsMasterResult isMasterResult = null; bool ok = false; try { var isMasterCommand = new CommandDocument("ismaster", 1); var tempResult = connection.RunCommand("admin", QueryFlags.SlaveOk, isMasterCommand, false); isMasterResult = new IsMasterResult(); isMasterResult.Initialize(isMasterCommand, tempResult.Response); if (!isMasterResult.Ok) { throw new MongoCommandException(isMasterResult); } MongoServerBuildInfo buildInfo; var buildInfoCommand = new CommandDocument("buildinfo", 1); var buildInfoResult = connection.RunCommand("admin", QueryFlags.SlaveOk, buildInfoCommand, false); if (buildInfoResult.Ok) { buildInfo = MongoServerBuildInfo.FromCommandResult(buildInfoResult); } else { // short term fix: if buildInfo fails due to auth we don't know the server version; see CSHARP-324 if (buildInfoResult.ErrorMessage != "need to login") { throw new MongoCommandException(buildInfoResult); } buildInfo = null; } ReplicaSetInformation replicaSetInformation = null; MongoServerInstanceType instanceType = MongoServerInstanceType.StandAlone; if (isMasterResult.ReplicaSetName != null) { var peers = isMasterResult.Hosts.Concat(isMasterResult.Passives).Concat(isMasterResult.Arbiters).ToList(); replicaSetInformation = new ReplicaSetInformation(isMasterResult.ReplicaSetName, isMasterResult.Primary, peers, isMasterResult.Tags); instanceType = MongoServerInstanceType.ReplicaSetMember; } else if (isMasterResult.Message != null && isMasterResult.Message == "isdbgrid") { instanceType = MongoServerInstanceType.ShardRouter; } var newServerInfo = new ServerInformation { BuildInfo = buildInfo, InstanceType = instanceType, IsArbiter = isMasterResult.IsArbiterOnly, IsMasterResult = isMasterResult, IsPassive = isMasterResult.IsPassive, IsPrimary = isMasterResult.IsPrimary, IsSecondary = isMasterResult.IsSecondary, MaxDocumentSize = isMasterResult.MaxBsonObjectSize, MaxMessageLength = isMasterResult.MaxMessageLength, ReplicaSetInformation = replicaSetInformation }; MongoServerState currentState; lock (_serverInstanceLock) { currentState = _state; } SetState(currentState, newServerInfo); ok = true; } finally { if (!ok) { ServerInformation currentServerInfo; lock (_serverInstanceLock) { currentServerInfo = _serverInfo; } // keep the current instance type, build info, and replica set info // as these aren't relevent to state and are likely still correct. var newServerInfo = new ServerInformation { BuildInfo = currentServerInfo.BuildInfo, InstanceType = currentServerInfo.InstanceType, IsArbiter = false, IsMasterResult = isMasterResult, IsPassive = false, IsPrimary = false, IsSecondary = false, MaxDocumentSize = currentServerInfo.MaxDocumentSize, MaxMessageLength = currentServerInfo.MaxMessageLength, ReplicaSetInformation = currentServerInfo.ReplicaSetInformation }; SetState(MongoServerState.Disconnected, newServerInfo); } } }
// constructors /// <summary> /// Initializes a new instance of the <see cref="MongoServerInstance"/> class. /// </summary> /// <param name="server">The server.</param> /// <param name="address">The address.</param> internal MongoServerInstance(MongoServer server, MongoServerAddress address) { _server = server; _address = address; _sequentialId = Interlocked.Increment(ref __nextSequentialId); _maxDocumentSize = MongoDefaults.MaxDocumentSize; _maxMessageLength = MongoDefaults.MaxMessageLength; _state = MongoServerState.Disconnected; _instanceType = MongoServerInstanceType.Unknown; _connectionPool = new MongoConnectionPool(this); _pingTimeAggregator = new PingTimeAggregator(5); _stateVerificationTimer = new Timer(o => StateVerificationTimerCallback(), null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); // Console.WriteLine("MongoServerInstance[{0}]: {1}", sequentialId, address); }
private void SetState( MongoServerState state, MongoServerInstanceType instanceType, bool isPrimary, bool isSecondary, bool isPassive, bool isArbiter, ReplicaSetInformation replicaSetInformation) { lock (_serverInstanceLock) { bool changed = false; bool replicaSetInformationIsDifferent = false; if ((_replicaSetInformation == null && replicaSetInformation != null) || (_replicaSetInformation != replicaSetInformation)) { replicaSetInformationIsDifferent = true; } if (_state != state || _instanceType != instanceType || replicaSetInformationIsDifferent || _isPrimary != isPrimary || _isSecondary != isSecondary || _isPassive != isPassive || _isArbiter != isArbiter) { changed = true; _state = state; _instanceType = instanceType; if (_replicaSetInformation != replicaSetInformation) { _replicaSetInformation = replicaSetInformation; } _isPrimary = isPrimary; _isSecondary = isSecondary; _isPassive = isPassive; _isArbiter = isArbiter; } if (changed) { if (_state == MongoServerState.Disconnected) { _connectionPool.Clear(); } OnStateChanged(); } } }
// constructors public InstanceTypeDependency(MongoServerInstanceType instanceType) { _instanceType = instanceType; }
// private methods private void LookupServerInformation(MongoConnection connection) { IsMasterResult isMasterResult = null; bool ok = false; try { var isMasterCommand = new CommandDocument("ismaster", 1); isMasterResult = RunCommandAs <IsMasterResult>(connection, "admin", isMasterCommand); MongoServerBuildInfo buildInfo; try { var buildInfoCommand = new CommandDocument("buildinfo", 1); var buildInfoResult = RunCommandAs <CommandResult>(connection, "admin", buildInfoCommand); buildInfo = MongoServerBuildInfo.FromCommandResult(buildInfoResult); } catch (MongoCommandException ex) { // short term fix: if buildInfo fails due to auth we don't know the server version; see CSHARP-324 if (ex.CommandResult.ErrorMessage != "need to login") { throw; } buildInfo = null; } ReplicaSetInformation replicaSetInformation = null; MongoServerInstanceType instanceType = MongoServerInstanceType.StandAlone; if (isMasterResult.IsReplicaSet) { var peers = isMasterResult.Hosts.Concat(isMasterResult.Passives).Concat(isMasterResult.Arbiters).ToList(); replicaSetInformation = new ReplicaSetInformation(isMasterResult.ReplicaSetName, isMasterResult.Primary, peers, isMasterResult.Tags, isMasterResult.ReplicaSetConfigVersion); instanceType = MongoServerInstanceType.ReplicaSetMember; } else if (isMasterResult.Message != null && isMasterResult.Message == "isdbgrid") { instanceType = MongoServerInstanceType.ShardRouter; } var featureContext = new FeatureContext { BuildInfo = buildInfo, Connection = connection, IsMasterResult = isMasterResult, ServerInstanceType = instanceType }; var featureSet = new FeatureSetDetector().DetectFeatureSet(featureContext); var newServerInfo = new ServerInformation { BuildInfo = buildInfo, FeatureSet = featureSet, InstanceType = instanceType, IsArbiter = isMasterResult.IsArbiterOnly, IsMasterResult = isMasterResult, IsPassive = isMasterResult.IsPassive, IsPrimary = isMasterResult.IsPrimary, IsSecondary = isMasterResult.IsSecondary, MaxBatchCount = isMasterResult.MaxWriteBatchSize, MaxDocumentSize = isMasterResult.MaxBsonObjectSize, MaxMessageLength = isMasterResult.MaxMessageLength, ReplicaSetInformation = replicaSetInformation }; MongoServerState currentState; lock (_serverInstanceLock) { currentState = _state; } SetState(currentState, newServerInfo); ok = true; } finally { if (!ok) { ServerInformation currentServerInfo; lock (_serverInstanceLock) { currentServerInfo = _serverInfo; } // keep the current instance type, build info, and replica set info // as these aren't relevent to state and are likely still correct. var newServerInfo = new ServerInformation { BuildInfo = currentServerInfo.BuildInfo, FeatureSet = currentServerInfo.FeatureSet, InstanceType = currentServerInfo.InstanceType, IsArbiter = false, IsMasterResult = isMasterResult, IsPassive = false, IsPrimary = false, IsSecondary = false, MaxDocumentSize = currentServerInfo.MaxDocumentSize, MaxMessageLength = currentServerInfo.MaxMessageLength, MaxBatchCount = currentServerInfo.MaxBatchCount, ReplicaSetInformation = currentServerInfo.ReplicaSetInformation }; SetState(MongoServerState.Disconnected, newServerInfo); } } }
// constructors public InstanceTypeDependency(MongoServerInstanceType instanceType) { _instanceType = instanceType; }