/// <summary> /// Initializes a new instance of the <see cref="DirectMongoServerProxy"/> class. /// </summary> /// <param name="sequentialId">The sequential id.</param> /// <param name="serverSettings">The server settings.</param> /// <param name="instance">The instance.</param> /// <param name="connectionAttempt">The connection attempt.</param> public DirectMongoServerProxy(int sequentialId, MongoServerProxySettings serverSettings, MongoServerInstance instance, int connectionAttempt) { _sequentialId = sequentialId; _settings = serverSettings; _instance = instance; _connectionAttempt = connectionAttempt; }
private void ProcessConnectedPrimaryStateChange(MongoServerInstance instance) { Interlocked.Exchange(ref _primary, instance); Interlocked.CompareExchange(ref _replicaSetName, instance.ReplicaSetInformation.Name, null); var members = instance.ReplicaSetInformation.Members; var configVersion = instance.ReplicaSetInformation.ConfigVersion; if (members.Any() && (!configVersion.HasValue || !_configVersion.HasValue || configVersion.Value > _configVersion.Value)) { if (configVersion.HasValue) { _configVersion = configVersion.Value; } // remove instances the primary doesn't know about and add instances we don't know about MakeInstancesMatchAddresses(members); } var instancesMarkedPrimary = Instances.Where(x => x.IsPrimary); foreach (var otherInstance in instancesMarkedPrimary) { if (!otherInstance.Address.Equals(instance.Address)) { otherInstance.UnsetPrimary(); } } }
protected BsonBinaryReaderSettings GetNodeAdjustedReaderSettings(MongoServerInstance node) { var readerSettings = _readerSettings.Clone(); readerSettings.MaxDocumentSize = node.MaxDocumentSize; return(readerSettings); }
protected BsonBinaryWriterSettings GetNodeAdjustedWriterSettings(MongoServerInstance node) { var writerSettings = _writerSettings.Clone(); writerSettings.MaxDocumentSize = node.MaxDocumentSize; return(writerSettings); }
public void Setup() { _server = Configuration.TestServer; _primary = Configuration.TestServer.Primary; _database = Configuration.TestDatabase; _database.Drop(); }
internal void Connect( TimeSpan timeout ) { server.ClearInstances(); var exceptions = new List <Exception>(); foreach (var address in server.Settings.Servers) { try { var serverInstance = new MongoServerInstance(server, address); server.AddInstance(serverInstance); try { serverInstance.Connect(server.Settings.SlaveOk); // TODO: what about timeout? } catch { server.RemoveInstance(serverInstance); throw; } return; } catch (Exception ex) { exceptions.Add(ex); } } var innerException = exceptions.FirstOrDefault(); var connectionException = new MongoConnectionException("Unable to connect to server.", innerException); if (exceptions.Count > 1) { connectionException.Data.Add("exceptions", exceptions); } throw connectionException; }
public void TestFixtureSetup() { _server = Configuration.TestServer; _adminDatabase = _server.GetDatabase("admin"); _database = Configuration.TestDatabase; _primary = _server.Primary; }
/// <summary> /// Initializes a new instance of the <see cref="MongoGridFSFileInfo"/> class. /// </summary> /// <param name="server">The server.</param> /// <param name="serverInstance">The server instance.</param> /// <param name="databaseName">Name of the database.</param> /// <param name="gridFSSettings">The GridFS settings.</param> /// <param name="remoteFileName">The remote file name.</param> /// <param name="createOptions">The create options.</param> public MongoGridFSFileInfo( MongoServer server, MongoServerInstance serverInstance, string databaseName, MongoGridFSSettings gridFSSettings, string remoteFileName, MongoGridFSCreateOptions createOptions) : this(server, serverInstance, databaseName, gridFSSettings) { if (remoteFileName == null) { throw new ArgumentNullException("remoteFileName"); } if (createOptions == null) { throw new ArgumentNullException("createOptions"); } _aliases = createOptions.Aliases; _chunkSize = (createOptions.ChunkSize == 0) ? gridFSSettings.ChunkSize : createOptions.ChunkSize; _contentType = createOptions.ContentType; _id = createOptions.Id; _metadata = createOptions.Metadata; _name = remoteFileName; _uploadDate = createOptions.UploadDate; _cached = true; // prevent values from being overwritten by automatic Refresh }
private void ProcessFirstResponse(ConnectResponse response) { var isMasterResponse = response.IsMasterResult.Response; // first response has to match replica set name in settings (if any) var replicaSetName = isMasterResponse["setName"].AsString; if (_server.Settings.ReplicaSetName != null && replicaSetName != _server.Settings.ReplicaSetName) { var message = string.Format( "Server at address '{0}' is a member of replica set '{1}' and not '{2}'.", response.ServerInstance.Address, replicaSetName, _server.Settings.ReplicaSetName); throw new MongoConnectionException(message); } _server.ReplicaSetName = replicaSetName; // find all valid addresses var validAddresses = new HashSet <MongoServerAddress>(); if (isMasterResponse.Contains("hosts")) { foreach (string address in isMasterResponse["hosts"].AsBsonArray) { validAddresses.Add(MongoServerAddress.Parse(address)); } } if (isMasterResponse.Contains("passives")) { foreach (string address in isMasterResponse["passives"].AsBsonArray) { validAddresses.Add(MongoServerAddress.Parse(address)); } } if (isMasterResponse.Contains("arbiters")) { foreach (string address in isMasterResponse["arbiters"].AsBsonArray) { validAddresses.Add(MongoServerAddress.Parse(address)); } } // remove server instances created from the seed list that turn out to be invalid var invalidInstances = _server.Instances.Where(i => !validAddresses.Contains(i.Address)).ToArray(); // force evaluation foreach (var invalidInstance in invalidInstances) { _server.RemoveInstance(invalidInstance); } // add any server instances that were missing from the seed list foreach (var address in validAddresses) { if (!_server.Instances.Any(i => i.Address == address)) { var missingInstance = new MongoServerInstance(_server, address); _server.AddInstance(missingInstance); QueueConnect(missingInstance); } } }
private void CreateActualProxy(MongoServerInstance instance, BlockingQueue <MongoServerInstance> connectionQueue) { lock (_lock) { if (instance.InstanceType == MongoServerInstanceType.ReplicaSetMember) { _serverProxy = new ReplicaSetMongoServerProxy(_settings, _instances, connectionQueue, _connectionAttempt); } else if (instance.InstanceType == MongoServerInstanceType.ShardRouter) { _serverProxy = new ShardedMongoServerProxy(_settings, _instances, connectionQueue, _connectionAttempt); } else if (instance.InstanceType == MongoServerInstanceType.StandAlone) { var otherInstances = _instances.Where(x => x != instance).ToList(); foreach (var otherInstance in otherInstances) { otherInstance.Disconnect(); } _serverProxy = new DirectMongoServerProxy(_settings, instance, _connectionAttempt); } else { throw new MongoConnectionException("The type of servers in the host list could not be determined."); } } }
/// <summary> /// 根据路径字符获得服务器 /// </summary> /// <param name="strObjTag">[Tag:Connection/Host@Port/DBName/Collection]</param> /// <returns></returns> public static MongoServer GetMongoServerBySvrPath(String strObjTag) { String strSvrPath = SystemManager.GetTagData(strObjTag); String[] strPath = strSvrPath.Split("/".ToCharArray()); if (strPath.Length == 1) { //[Tag:Connection if (_mongoConnSvrLst.ContainsKey(strPath[0])) { return(_mongoConnSvrLst[strPath[0]]); } } if (strPath.Length > (int)PathLv.InstanceLv) { if (strPath[0] == strPath[1]) { //[Tag:Connection/Connection/DBName/Collection] return(_mongoConnSvrLst[strPath[0]]); } //[Tag:Connection/Host@Port/DBName/Collection] String strInstKey = String.Empty; strInstKey = strPath[(int)PathLv.ConnectionLv] + "/" + strPath[(int)PathLv.InstanceLv]; if (_mongoInstanceLst.ContainsKey(strInstKey)) { MongoServerInstance mongoInstance = _mongoInstanceLst[strInstKey]; return(MongoServer.Create(mongoInstance.Settings)); } } return(null); }
/// <summary> /// Ensures that the instance is in the collection. /// </summary> /// <param name="instance">The instance.</param> public void EnsureContains(MongoServerInstance instance) { lock (_connectedInstancesLock) { if (_instanceLookup.ContainsKey(instance)) { return; } var node = new LinkedListNode <InstanceWithPingTime>(new InstanceWithPingTime { Instance = instance, CachedAveragePingTime = instance.AveragePingTime }); if (_instances.Count == 0 || _instances.First.Value.CachedAveragePingTime > node.Value.CachedAveragePingTime) { _instances.AddFirst(node); } else { var current = _instances.First; while (current.Next != null && node.Value.CachedAveragePingTime > current.Next.Value.CachedAveragePingTime) { current = current.Next; } _instances.AddAfter(current, node); } _instanceLookup.Add(instance, node); instance.AveragePingTimeChanged += InstanceAveragePingTimeChanged; } }
// public methods public Exception ToWriteConcernException(MongoServerInstance serverInstance, BulkWriteException bulkWriteException) { var writeConcernResult = ToWriteConcernResult(bulkWriteException.Result, bulkWriteException); writeConcernResult.ServerInstance = serverInstance; var exception = ExceptionMapper.Map(writeConcernResult.Response); if (exception == null) { exception = ExceptionMapper.Map(writeConcernResult); } if (exception == null) { exception = new WriteConcernException(bulkWriteException.Message, writeConcernResult); } var writeConcernException = exception as WriteConcernException; if (writeConcernException != null) { writeConcernException.Data["results"] = new List <WriteConcernResult>(new[] { writeConcernResult }); } return(exception); // usually a WriteConcernException unless ExceptionMapper chose a different type }
public void Setup() { _server = LegacyTestConfiguration.Server; _primary = LegacyTestConfiguration.Server.Primary; _database = LegacyTestConfiguration.Database; _database.Drop(); }
/// <summary> /// Export Collection /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ExportCollectionToolStripMenuItem_Click(object sender, EventArgs e) { if (!MongoPathCheck()) { return; } var MongoImportExport = new MongodbDosCommand.StruImportExport(); MongoServerInstance Mongosrv = SystemManager.GetCurrentServer().Instance; MongoImportExport.HostAddr = Mongosrv.Address.Host; MongoImportExport.Port = Mongosrv.Address.Port; MongoImportExport.DBName = SystemManager.GetCurrentDataBase().Name; MongoImportExport.CollectionName = SystemManager.GetCurrentCollection().Name; var dumpFile = new SaveFileDialog { Filter = MongoDbHelper.TxtFilter, CheckFileExists = false }; //if the file not exist,the server will create a new one if (dumpFile.ShowDialog() == DialogResult.OK) { MongoImportExport.FileName = dumpFile.FileName; } MongoImportExport.Direct = MongodbDosCommand.ImprotExport.Export; String DosCommand = MongodbDosCommand.GetMongoImportExportCommandLine(MongoImportExport); RunCommand(DosCommand); }
// constructors public FailPoint(string name, MongoServer server, MongoServerInstance serverInstance) { if (name == null) { throw new ArgumentNullException("name"); } if (server == null) { throw new ArgumentNullException("server"); } if (serverInstance == null) { throw new ArgumentNullException("serverInstance"); } if (server.RequestServerInstance != null) { throw new InvalidOperationException("FailPoint cannot be used when you are already in a RequestStart."); } _name = name; _server = server; _serverInstance = serverInstance; _adminDatabase = server.GetDatabase("admin"); _request = server.RequestStart(serverInstance); }
/// <summary> /// Indicates if the instance exists in the chooser. /// </summary> /// <param name="instance">The instance.</param> /// <returns> /// <c>true</c> if [contains] [the specified instance]; otherwise, <c>false</c>. /// </returns> public bool Contains(MongoServerInstance instance) { lock (_lock) { return _instances.Contains(instance); } }
internal void Connect( TimeSpan timeout ) { server.ClearInstances(); var exceptions = new List<Exception>(); foreach (var address in server.Settings.Servers) { try { var serverInstance = new MongoServerInstance(server, address); server.AddInstance(serverInstance); try { serverInstance.Connect(server.Settings.SlaveOk); // TODO: what about timeout? } catch { server.RemoveInstance(serverInstance); throw; } return; } catch (Exception ex) { exceptions.Add(ex); } } var innerException = exceptions.FirstOrDefault(); var connectionException = new MongoConnectionException("Unable to connect to server", innerException); if (exceptions.Count > 1) { connectionException.Data.Add("exceptions", exceptions); } throw connectionException; }
public void OneTimeSetUp() { _server = LegacyTestConfiguration.Server; _primary = LegacyTestConfiguration.Server.Primary; _database = LegacyTestConfiguration.Database; // TODO: DropDatabase //_database.Drop(); }
// constructors internal MongoConnection(MongoConnectionPool connectionPool) { this.serverInstance = connectionPool.ServerInstance; this.connectionPool = connectionPool; this.generationId = connectionPool.GenerationId; this.createdAt = DateTime.UtcNow; this.state = MongoConnectionState.Initial; }
// constructors internal MongoConnection(MongoConnectionPool connectionPool) { _serverInstance = connectionPool.ServerInstance; _connectionPool = connectionPool; _generationId = connectionPool.GenerationId; _createdAt = DateTime.UtcNow; _state = MongoConnectionState.Initial; }
public void TestFixtureSetUp() { _primary = Configuration.TestServer.Primary; _collection = Configuration.TestCollection; _collectionName = Configuration.TestCollection.Name; _database = Configuration.TestDatabase; _databaseName = Configuration.TestDatabase.Name; }
// private methods private void AddInstance(MongoServerInstance instance) { lock (_lock) { _instances.Add(instance); instance.StateChanged += InstanceStateChanged; ProcessInstanceStateChange(instance); } }
internal MongoConnectionPool( MongoServerInstance serverInstance ) { this.server = serverInstance.Server; this.serverInstance = serverInstance; poolSize = 0; timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10)); }
public MongoDatabaseTests() { _server = LegacyTestConfiguration.Server; _primary = LegacyTestConfiguration.Server.Primary; _database = LegacyTestConfiguration.Database; _adminDatabase = _server.GetDatabase("admin"); // TODO: DropDatabase //_database.Drop(); }
internal MongoConnectionPool( MongoServerInstance serverInstance ) { this.server = serverInstance.Server; this.serverInstance = serverInstance; poolSize = 0; timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10)); }
private void ProcessConnectedSecondaryStateChange(MongoServerInstance instance) { var address = instance.ReplicaSetInformation.Primary; if (address != null) { // make sure the primary exists in the instance list EnsureInstanceWithAddress(address); } }
// constructors internal MongoConnectionPool(MongoServerInstance serverInstance) { _server = serverInstance.Server; _serverInstance = serverInstance; _poolSize = 0; var dueTime = TimeSpan.FromSeconds(0); var period = TimeSpan.FromSeconds(10); _timer = new Timer(TimerCallback, null, dueTime, period); }
/// <summary> /// Processes the connected instance state change. /// </summary> /// <param name="instance">The instance.</param> protected override void ProcessConnectedInstanceStateChange(MongoServerInstance instance) { if (instance.IsPrimary) { ProcessConnectedPrimaryStateChange(instance); } else { ProcessConnectedSecondaryStateChange(instance); } }
// constructors internal MongoConnectionPool(MongoServerInstance serverInstance) { _server = serverInstance.Server; _serverInstance = serverInstance; _poolSize = 0; var dueTime = TimeSpan.FromSeconds(0); var period = TimeSpan.FromSeconds(10); _timer = new Timer(TimerCallback, null, dueTime, period); }
private void QueueConnect(MongoServerInstance serverInstance) { var args = new ConnectArgs { ServerInstance = serverInstance, ResponseQueue = _responseQueue }; ThreadPool.QueueUserWorkItem(ConnectWorkItem, args); _connects.Add(args); }
// constructors public MongoGridFSFileInfoSerializer( MongoServer server, MongoServerInstance serverInstance, string databaseName, MongoGridFSSettings gridFSSettings) { _server = server; _serverInstance = serverInstance; _databaseName = databaseName; _gridFSSettings = gridFSSettings; }
private void RemoveInstance(MongoServerInstance instance) { _connectedInstances.Remove(instance); lock (_lock) { _instances.Remove(instance); instance.StateChanged -= InstanceStateChanged; instance.DisconnectPermanently(); ProcessInstanceStateChange(instance); } }
/// <summary> /// Gets a list of primary and secondary instances. /// </summary> /// <param name="primary">The current primary.</param> /// <returns>The list of primary and secondary instances.</returns> public List<InstanceWithPingTime> GetPrimaryAndSecondaries(MongoServerInstance primary) { lock (_connectedInstancesLock) { // note: make copies of InstanceWithPingTime values because they can change after we return return _instances .Where(x => x.Instance == primary || x.Instance.IsSecondary) .Select(x => new InstanceWithPingTime { Instance = x.Instance, CachedAveragePingTime = x.CachedAveragePingTime }) .ToList(); } }
/// <summary> /// Determines whether the instance is a valid. If not, the instance is removed. /// </summary> /// <param name="instance">The instance.</param> /// <returns> /// <c>true</c> if the instance is valid; otherwise, <c>false</c>. /// </returns> protected override bool IsValidInstance(MongoServerInstance instance) { if (instance.InstanceType != MongoServerInstanceType.ReplicaSetMember) { return(false); } // read _replicaSetName in a thread-safe way var replicaSetName = Interlocked.CompareExchange(ref _replicaSetName, null, null); return(replicaSetName == null || replicaSetName == instance.ReplicaSetInformation.Name); }
private void ProcessConnectedPrimaryStateChange(MongoServerInstance instance) { Interlocked.CompareExchange(ref _replicaSetName, instance.ReplicaSetInformation.Name, null); var members = instance.ReplicaSetInformation.Members; if (members.Any()) { // remove instances the primary doesn't know about and add instances we don't know about MakeInstancesMatchAddresses(members); } }
// constructors internal MongoConnectionPool(MongoServerInstance serverInstance) { _settings = serverInstance.Settings; _serverInstance = serverInstance; _poolSize = 0; _defaultAcquireConnectionOptions = new AcquireConnectionOptions { OkToAvoidWaitingByCreatingNewConnection = true, OkToExceedMaxConnectionPoolSize = false, OkToExceedWaitQueueSize = false, WaitQueueTimeout = _settings.WaitQueueTimeout }; }
// public methods /// <summary> /// Adds the specified instance. /// </summary> /// <param name="instance">The instance.</param> public void Add(MongoServerInstance instance) { lock (_lock) { var index = _instances.FindIndex(x => x.AveragePingTime >= instance.AveragePingTime); if (index == -1) { _instances.Add(instance); } else { _instances.Insert(index + 1, instance); } instance.AveragePingTimeChanged += InstanceAveragePingTimeChanged; } }
/// <summary> /// Determines whether the instance is a valid. If not, the instance is removed. /// </summary> /// <param name="instance">The instance.</param> /// <returns> /// <c>true</c> if the instance is valid; otherwise, <c>false</c>. /// </returns> protected abstract bool IsValidInstance(MongoServerInstance instance);
/// <summary> /// Determines whether the instance is a valid. If not, the instance is removed. /// </summary> /// <param name="instance">The instance.</param> /// <returns> /// <c>true</c> if the instance is valid; otherwise, <c>false</c>. /// </returns> protected override bool IsValidInstance(MongoServerInstance instance) { return instance.InstanceType == MongoServerInstanceType.ShardRouter; }
/// <summary> /// Ensures that an instance with the address exists. /// </summary> /// <param name="address">The address.</param> protected void EnsureInstanceWithAddress(MongoServerAddress address) { if (address == null) { throw new ArgumentNullException("address"); } lock (_lock) { if (!_instances.Any(x => x.Address == address)) { var instance = new MongoServerInstance(_server, address); AddInstance(instance); if (_state != MongoServerState.Disconnecting && _state != MongoServerState.Disconnected) { _state = MongoServerState.Connecting; ConnectInstance(instance); } } } }
// constructors /// <summary> /// Initializes a new instance of the <see cref="DirectMongoServerProxy"/> class. /// </summary> /// <param name="settings">The settings.</param> public DirectMongoServerProxy(MongoServerSettings settings) { _settings = settings; _instance = new MongoServerInstance(settings, settings.Servers.First()); }
private void ProcessInstanceStateChange(MongoServerInstance instance) { lock (_lock) { if (instance.State == MongoServerState.Connected && _instances.Contains(instance)) { if (!IsValidInstance(instance)) { RemoveInstance(instance); // TODO: log this... return; } if (instance.IsMasterResult.MyAddress != null && instance.Address != instance.IsMasterResult.MyAddress) { // NOTE: if this gets set inside the MongoServerInstance, then there is a race condition that could cause // the instance to get added more than once to the list because the changes occur under different locks. // I don't like this and would rather it be in the MongoServerInstance, but haven't figured out how to do // it yet. // One solution is for every instance change to check to see if two instances exist in the list and remove // the other one, as the current one is more up-to-date. instance.Address = instance.IsMasterResult.MyAddress; } if (!_connectedInstances.Contains(instance)) { _connectedInstances.Add(instance); } ProcessConnectedInstanceStateChange(instance); } else { _connectedInstances.Remove(instance); } SetState(DetermineServerState(_state, _instances)); } }
private void ConnectInstance(MongoServerInstance instance) { Interlocked.Increment(ref _outstandingInstanceConnections); ThreadPool.QueueUserWorkItem(_ => { try { instance.Connect(); } catch { // instance is keeping it's last ConnectionException } finally { Interlocked.Decrement(ref _outstandingInstanceConnections); } }); }
private void RemoveInstance(MongoServerInstance instance) { _connectedInstances.Remove(instance); lock (_lock) { _instances.Remove(instance); instance.StateChanged -= InstanceStateChanged; instance.DisconnectPermanently(); ProcessInstanceStateChange(instance); } }
private void QueueConnect(MongoServerInstance serverInstance) { var args = new ConnectArgs { ServerInstance = serverInstance, ResponseQueue = _responseQueue }; ThreadPool.QueueUserWorkItem(ConnectWorkItem, args); _connects.Add(args); }
/// <summary> /// Processes the connected instance state change. /// </summary> /// <param name="instance">The instance.</param> protected override void ProcessConnectedInstanceStateChange(MongoServerInstance instance) { if (instance.IsPrimary) { ProcessConnectedPrimaryStateChange(instance); } else { ProcessConnectedSecondaryStateChange(instance); } }
private void ProcessConnectedPrimaryStateChange(MongoServerInstance instance) { Interlocked.CompareExchange(ref _replicaSetName, instance.ReplicaSetInformation.Name, null); var members = instance.ReplicaSetInformation.Members; if (members.Any()) { // remove instances the primary doesn't know about and add instances we don't know about MakeInstancesMatchAddresses(members); } var instancesMarkedPrimary = Instances.Where(x => x.IsPrimary); foreach (var otherInstance in instancesMarkedPrimary) { if (!otherInstance.Address.Equals(instance.Address)) { otherInstance.UnsetPrimary(); } } }
private void ProcessFirstResponse(ConnectResponse response) { var isMasterResponse = response.IsMasterResult.Response; // first response has to match replica set name in settings (if any) var replicaSetName = isMasterResponse["setName"].AsString; if (_server.Settings.ReplicaSetName != null && replicaSetName != _server.Settings.ReplicaSetName) { var message = string.Format( "Server at address '{0}' is a member of replica set '{1}' and not '{2}'.", response.ServerInstance.Address, replicaSetName, _server.Settings.ReplicaSetName); throw new MongoConnectionException(message); } _server.ReplicaSetName = replicaSetName; // find all valid addresses var validAddresses = new HashSet<MongoServerAddress>(); if (isMasterResponse.Contains("hosts")) { foreach (string address in isMasterResponse["hosts"].AsBsonArray) { validAddresses.Add(MongoServerAddress.Parse(address)); } } if (isMasterResponse.Contains("passives")) { foreach (string address in isMasterResponse["passives"].AsBsonArray) { validAddresses.Add(MongoServerAddress.Parse(address)); } } if (isMasterResponse.Contains("arbiters")) { foreach (string address in isMasterResponse["arbiters"].AsBsonArray) { validAddresses.Add(MongoServerAddress.Parse(address)); } } // remove server instances created from the seed list that turn out to be invalid var invalidInstances = _server.Instances.Where(i => !validAddresses.Contains(i.Address)).ToArray(); // force evaluation foreach (var invalidInstance in invalidInstances) { _server.RemoveInstance(invalidInstance); } // add any server instances that were missing from the seed list foreach (var address in validAddresses) { if (!_server.Instances.Any(i => i.Address == address)) { var missingInstance = new MongoServerInstance(_server, address); _server.AddInstance(missingInstance); QueueConnect(missingInstance); } } }
private void ProcessConnectedSecondaryStateChange(MongoServerInstance instance) { var address = instance.ReplicaSetInformation.Primary; if (address != null) { // make sure the primary exists in the instance list EnsureInstanceWithAddress(address); } }
private void ProcessInstanceStateChange(MongoServerInstance instance) { List<MongoServerInstance> currentInstances; MongoServerState currentState; lock (_lock) { currentInstances = _instances; currentState = _state; } if (currentInstances.Contains(instance)) { if (instance.State == MongoServerState.Connected) { if (!IsValidInstance(instance)) { RemoveInstance(instance); return; } if (currentState != MongoServerState.Disconnecting && currentState != MongoServerState.Disconnected) { _connectedInstances.EnsureContains(instance); ProcessConnectedInstanceStateChange(instance); } } else { _connectedInstances.Remove(instance); } } SetState(DetermineServerState(currentState, currentInstances)); }
private void CreateActualProxy(MongoServerInstance instance, BlockingQueue<MongoServerInstance> connectionQueue) { lock (_lock) { if (instance.InstanceType == MongoServerInstanceType.ReplicaSetMember) { _serverProxy = new ReplicaSetMongoServerProxy(_settings, _instances, connectionQueue, _connectionAttempt); } else if (instance.InstanceType == MongoServerInstanceType.ShardRouter) { _serverProxy = new ShardedMongoServerProxy(_settings, _instances, connectionQueue, _connectionAttempt); } else if (instance.InstanceType == MongoServerInstanceType.StandAlone) { var otherInstances = _instances.Where(x => x != instance).ToList(); foreach (var otherInstance in otherInstances) { otherInstance.Disconnect(); } _serverProxy = new DirectMongoServerProxy(_settings, instance, _connectionAttempt); } else { throw new MongoConnectionException("The type of servers in the host list could not be determined."); } } }
/// <summary> /// Processes the connected instance state change. /// </summary> /// <param name="instance">The instance.</param> protected virtual void ProcessConnectedInstanceStateChange(MongoServerInstance instance) { }
/// <summary> /// Ensures that the instance is in the collection. /// </summary> /// <param name="instance">The instance.</param> public void EnsureContains(MongoServerInstance instance) { lock (_connectedInstancesLock) { if (_instanceLookup.ContainsKey(instance)) { return; } var node = new LinkedListNode<InstanceWithPingTime>(new InstanceWithPingTime { Instance = instance, CachedAveragePingTime = instance.AveragePingTime }); if (_instances.Count == 0 || _instances.First.Value.CachedAveragePingTime > node.Value.CachedAveragePingTime) { _instances.AddFirst(node); } else { var current = _instances.First; while (current.Next != null && node.Value.CachedAveragePingTime > current.Next.Value.CachedAveragePingTime) { current = current.Next; } _instances.AddAfter(current, node); } _instanceLookup.Add(instance, node); instance.AveragePingTimeChanged += InstanceAveragePingTimeChanged; } }
// private methods private void AddInstance(MongoServerInstance instance) { lock (_lock) { _instances.Add(instance); instance.StateChanged += InstanceStateChanged; ProcessInstanceStateChange(instance); } }
/// <summary> /// Removes the specified instance. /// </summary> /// <param name="instance">The instance.</param> public void Remove(MongoServerInstance instance) { lock (_connectedInstancesLock) { LinkedListNode<InstanceWithPingTime> node; if (!_instanceLookup.TryGetValue(instance, out node)) { return; } instance.AveragePingTimeChanged -= InstanceAveragePingTimeChanged; _instanceLookup.Remove(instance); _instances.Remove(node); } }
private void ProcessInstanceStateChange(MongoServerInstance instance) { lock (_lock) { if (_instances.Contains(instance)) { if (instance.State == MongoServerState.Connected) { if (!IsValidInstance(instance)) { RemoveInstance(instance); return; } if (instance.Address != instance.IsMasterResult.MyAddress) { if (!_instances.Any(x => x.Address == instance.IsMasterResult.MyAddress)) { instance.Address = instance.IsMasterResult.MyAddress; } else { // we need to get rid of the duplicate. RemoveInstance(instance); return; } } if (_state != MongoServerState.Disconnecting && _state != MongoServerState.Disconnected) { _connectedInstances.EnsureContains(instance); ProcessConnectedInstanceStateChange(instance); } } else { _connectedInstances.Remove(instance); } } _state = DetermineServerState(_state, _instances); } }
/// <summary> /// Determines whether the instance is a valid. If not, the instance is removed. /// </summary> /// <param name="instance">The instance.</param> /// <returns> /// <c>true</c> if the instance is valid; otherwise, <c>false</c>. /// </returns> protected override bool IsValidInstance(MongoServerInstance instance) { if (instance.InstanceType != MongoServerInstanceType.ReplicaSetMember) { return false; } // read _replicaSetName in a thread-safe way var replicaSetName = Interlocked.CompareExchange(ref _replicaSetName, null, null); return replicaSetName == null || instance.ReplicaSetInformation.Name == null || replicaSetName == instance.ReplicaSetInformation.Name; }
/// <summary> /// Ensures that an instance with the address exists. /// </summary> /// <param name="address">The address.</param> protected void EnsureInstanceWithAddress(MongoServerAddress address) { lock (_lock) { if (!_instances.Any(x => x.Address == address)) { var instance = new MongoServerInstance(_server, address); AddInstance(instance); if (_state != MongoServerState.Disconnecting && _state != MongoServerState.Disconnected) { SetState(MongoServerState.Connecting); ConnectInstance(instance); } } } }
/// <summary> /// Initializes a new instance of the <see cref="DirectMongoServerProxy"/> class. /// </summary> /// <param name="serverSettings">The server settings.</param> /// <param name="instance">The instance.</param> /// <param name="connectionAttempt">The connection attempt.</param> public DirectMongoServerProxy(MongoServerSettings serverSettings, MongoServerInstance instance, int connectionAttempt) { _settings = serverSettings; _instance = instance; _connectionAttempt = connectionAttempt; }