/// <summary> /// Initializes a new instance of the <see cref="MultipleInstanceMongoServerProxy"/> class. /// </summary> /// <param name="settings">The settings.</param> /// <param name="instances">The instances.</param> /// <param name="connectionQueue">The state change queue.</param> /// <param name="connectionAttempt">The connection attempt.</param> /// <remarks>This constructor is used when the instances have already been instructed to connect.</remarks> protected MultipleInstanceMongoServerProxy(MongoServerSettings settings, IEnumerable <MongoServerInstance> instances, BlockingQueue <MongoServerInstance> connectionQueue, int connectionAttempt) { _state = MongoServerState.Connecting; _settings = settings; _connectedInstances = new ConnectedInstanceCollection(); _connectionAttempt = connectionAttempt; _outstandingInstanceConnections = connectionQueue.Count; ThreadPool.QueueUserWorkItem(_ => { while (connectionQueue.Count > 0) { connectionQueue.Dequeue(); Interlocked.Decrement(ref _outstandingInstanceConnections); } }); // It's important to have our own copy of this list because it might get modified during iteration. _instances = instances.ToList(); foreach (var instance in instances) { instance.StateChanged += InstanceStateChanged; ProcessInstanceStateChange(instance); } }
/// <summary> /// Initializes a new instance of the <see cref="ShardedMongoServerProxy"/> class. /// </summary> /// <param name="server">The server.</param> /// <param name="instances">The instances.</param> /// <param name="connectionQueue">The state change queue.</param> /// <param name="connectionAttempt">The connection attempt.</param> /// <remarks>This constructor is used when the instances have already been instructed to connect.</remarks> protected MultipleInstanceMongoServerProxy(MongoServer server, IEnumerable<MongoServerInstance> instances, BlockingQueue<MongoServerInstance> connectionQueue, int connectionAttempt) { _state = MongoServerState.Connecting; _server = server; _connectedInstances = new ConnectedInstanceCollection(); _connectionAttempt = connectionAttempt; _outstandingInstanceConnections = connectionQueue.Count; ThreadPool.QueueUserWorkItem(_ => { while (connectionQueue.Count > 0) { var instance = connectionQueue.Dequeue(); Interlocked.Decrement(ref _outstandingInstanceConnections); } }); // It's important to have our own copy of this list because it might get modified during iteration. _instances = instances.ToList(); foreach (var instance in instances) { instance.StateChanged += InstanceStateChanged; ProcessInstanceStateChange(instance); } }
// protected methods /// <summary> /// Chooses the server instance. /// </summary> /// <param name="connectedInstances">The connected instances.</param> /// <param name="readPreference">The read preference.</param> /// <returns>A MongoServerInstance.</returns> protected override MongoServerInstance ChooseServerInstance(ConnectedInstanceCollection connectedInstances, ReadPreference readPreference) { var instancesWithPingTime = connectedInstances.GetAllInstances(); if (instancesWithPingTime.Count == 0) { return(null); } else if (instancesWithPingTime.Count == 1) { return(instancesWithPingTime[0].Instance); } else { var secondaryAcceptableLatency = Settings.SecondaryAcceptableLatency; var minPingTime = instancesWithPingTime[0].CachedAveragePingTime; var maxPingTime = minPingTime + secondaryAcceptableLatency; var n = instancesWithPingTime.Count(i => i.CachedAveragePingTime <= maxPingTime); lock (_randomLock) { var index = _random.Next(n); return(instancesWithPingTime[index].Instance); // return random instance } } }
/// <summary> /// Initializes a new instance of the <see cref="ShardedMongoServerProxy"/> class. /// </summary> /// <param name="server">The server.</param> protected MultipleInstanceMongoServerProxy(MongoServer server) { _server = server; _connectedInstances = new ConnectedInstanceCollection(); _instances = new List<MongoServerInstance>(); MakeInstancesMatchAddresses(server.Settings.Servers); }
/// <summary> /// Initializes a new instance of the <see cref="MultipleInstanceMongoServerProxy"/> class. /// </summary> /// <param name="settings">The settings.</param> protected MultipleInstanceMongoServerProxy(MongoServerSettings settings) { _settings = settings; _connectedInstances = new ConnectedInstanceCollection(); _instances = new List <MongoServerInstance>(); MakeInstancesMatchAddresses(settings.Servers); }
/// <summary> /// Initializes a new instance of the <see cref="MultipleInstanceMongoServerProxy"/> class. /// </summary> /// <param name="sequentialId">The sequential id.</param> /// <param name="settings">The settings.</param> protected MultipleInstanceMongoServerProxy(int sequentialId, MongoServerProxySettings settings) { _sequentialId = sequentialId; _settings = settings; _connectedInstances = new ConnectedInstanceCollection(); _instances = new List<MongoServerInstance>(); MakeInstancesMatchAddresses(settings.Servers); }
/// <summary> /// Initializes a new instance of the <see cref="ShardedMongoServerProxy"/> class. /// </summary> /// <param name="server">The server.</param> protected MultipleConnectionMongoServerProxy(MongoServer server) { _server = server; _instances = new List<MongoServerInstance>(); _connectedInstances = new ConnectedInstanceCollection(); _stateChangeQueue = new BlockingQueue<MongoServerInstance>(); MakeInstancesMatchAddresses(server.Settings.Servers); _stateChangeThread = new Thread(ProcessStateChanges); _stateChangeThread.IsBackground = true; _stateChangeThread.Start(); }
/// <summary> /// Initializes a new instance of the <see cref="ShardedMongoServerProxy"/> class. /// </summary> /// <param name="server">The server.</param> /// <param name="instances">The instances.</param> /// <param name="stateChangedQueue">The state change queue.</param> /// <param name="connectionAttempt">The connection attempt.</param> protected MultipleConnectionMongoServerProxy(MongoServer server, IEnumerable<MongoServerInstance> instances, BlockingQueue<MongoServerInstance> stateChangedQueue, int connectionAttempt) { _server = server; _instances = new List<MongoServerInstance>(); _connectedInstances = new ConnectedInstanceCollection(); _connectionAttempt = connectionAttempt; _stateChangeQueue = stateChangedQueue; foreach (var instance in instances) { AddInstance(instance); } _stateChangeThread = new Thread(ProcessStateChanges); _stateChangeThread.IsBackground = true; _stateChangeThread.Start(); }
// protected methods protected override MongoServerInstance ChooseServerInstance(ConnectedInstanceCollection connectedInstances, ReadPreference readPreference) { var secondaryAcceptableLatency = Server.Settings.SecondaryAcceptableLatency; switch (readPreference.ReadPreferenceMode) { case ReadPreferenceMode.Primary: return(connectedInstances.GetPrimary()); case ReadPreferenceMode.PrimaryPreferred: var primary = connectedInstances.GetPrimary(); if (primary != null) { return(primary); } else { return(GetMatchingInstance(connectedInstances.GetSecondaries(), readPreference, secondaryAcceptableLatency)); } case ReadPreferenceMode.Secondary: return(GetMatchingInstance(connectedInstances.GetSecondaries(), readPreference, secondaryAcceptableLatency)); case ReadPreferenceMode.SecondaryPreferred: var secondary = GetMatchingInstance(connectedInstances.GetSecondaries(), readPreference, secondaryAcceptableLatency); if (secondary != null) { return(secondary); } else { return(connectedInstances.GetPrimary()); } case ReadPreferenceMode.Nearest: return(GetMatchingInstance(connectedInstances.GetPrimaryAndSecondaries(), readPreference, secondaryAcceptableLatency)); default: throw new MongoInternalException("Invalid ReadPreferenceMode."); } }
// protected methods protected override MongoServerInstance ChooseServerInstance(ConnectedInstanceCollection connectedInstances, ReadPreference readPreference) { var secondaryAcceptableLatency = Settings.SecondaryAcceptableLatency; switch (readPreference.ReadPreferenceMode) { case ReadPreferenceMode.Primary: return connectedInstances.GetPrimary(); case ReadPreferenceMode.PrimaryPreferred: var primary = connectedInstances.GetPrimary(); if (primary != null) { return primary; } else { return GetMatchingInstance(connectedInstances.GetSecondaries(), readPreference, secondaryAcceptableLatency); } case ReadPreferenceMode.Secondary: return GetMatchingInstance(connectedInstances.GetSecondaries(), readPreference, secondaryAcceptableLatency); case ReadPreferenceMode.SecondaryPreferred: var secondary = GetMatchingInstance(connectedInstances.GetSecondaries(), readPreference, secondaryAcceptableLatency); if (secondary != null) { return secondary; } else { return connectedInstances.GetPrimary(); } case ReadPreferenceMode.Nearest: return GetMatchingInstance(connectedInstances.GetPrimaryAndSecondaries(), readPreference, secondaryAcceptableLatency); default: throw new MongoInternalException("Invalid ReadPreferenceMode."); } }
// protected methods /// <summary> /// Chooses the server instance. /// </summary> /// <param name="connectedInstances">The connected instances.</param> /// <param name="readPreference">The read preference.</param> /// <returns>A MongoServerInstance.</returns> protected override MongoServerInstance ChooseServerInstance(ConnectedInstanceCollection connectedInstances, ReadPreference readPreference) { var instancesWithPingTime = connectedInstances.GetAllInstances(); if (instancesWithPingTime.Count == 0) { return null; } else if (instancesWithPingTime.Count == 1) { return instancesWithPingTime[0].Instance; } else { var minPingTime = instancesWithPingTime[0].CachedAveragePingTime; var maxPingTime = minPingTime + readPreference.SecondaryAcceptableLatency; var n = instancesWithPingTime.Count(i => i.CachedAveragePingTime <= maxPingTime); lock (_randomLock) { var index = _random.Next(n); return instancesWithPingTime[index].Instance; // return random instance } } }
// protected methods /// <summary> /// Chooses the server instance. /// </summary> /// <param name="connectedInstances">The connected instances.</param> /// <param name="readPreference">The read preference.</param> /// <returns>A MongoServerInstance.</returns> protected abstract MongoServerInstance ChooseServerInstance(ConnectedInstanceCollection connectedInstances, ReadPreference readPreference);
// protected methods protected override MongoServerInstance ChooseServerInstance(ConnectedInstanceCollection connectedInstances, ReadPreference readPreference) { return connectedInstances.ChooseServerInstance(readPreference); }
// protected methods /// <summary> /// Chooses the server instance. /// </summary> /// <param name="connectedInstances">The connected instances.</param> /// <param name="readPreference">The read preference.</param> /// <returns>A MongoServerInstance.</returns> protected abstract MongoServerInstance ChooseServerInstance(ConnectedInstanceCollection connectedInstances, ReadPreference readPreference);
// protected methods /// <summary> /// Chooses the server instance. /// </summary> /// <param name="connectedInstances">The connected instances.</param> /// <param name="readPreference">The read preference.</param> /// <returns>A MongoServerInstance.</returns> protected override MongoServerInstance ChooseServerInstance(ConnectedInstanceCollection connectedInstances, ReadPreference readPreference) { return(connectedInstances.ChooseServerInstance(ReadPreference.Primary)); }