Maintains a sorted list of connected instances by ping time.
예제 #1
0
        /// <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);
        }
예제 #5
0
        /// <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);
 }
예제 #14
0
 // 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));
 }