Exemple #1
0
        private BlockingQueue <QueryNodeResponse> QueueSeedListQueries()
        {
            var responseQueue = new BlockingQueue <QueryNodeResponse>();
            var addresses     = server.Settings.Servers.ToList();
            var endPoints     = server.EndPoints.ToList();

            for (int i = 0; i < addresses.Count; i++)
            {
                var args = new QueryNodeParameters {
                    Address       = addresses[i],
                    EndPoint      = endPoints[i],
                    ResponseQueue = responseQueue
                };
                ThreadPool.QueueUserWorkItem(QueryNodeWorkItem, args);
                queries.Add(addresses[i]);
            }
            return(responseQueue);
        }
Exemple #2
0
        public void Connect(
            TimeSpan timeout
            )
        {
            // query all servers in seed list in parallel (they will report responses back through the responsesQueue)
            var responsesQueue = QueueSeedListQueries();

            // process the responses as they come back and stop as soon as we find the primary (unless SlaveOk is true)
            // stragglers will continue to report responses to the responsesQueue but no one will read them
            // and eventually it will all get garbage collected

            var exceptions = new List <Exception>();
            var timeoutAt  = DateTime.UtcNow + timeout;

            while (responses.Count < queries.Count)
            {
                var timeRemaining = timeoutAt - DateTime.UtcNow;
                var response      = responsesQueue.Dequeue(timeRemaining);
                if (response == null)
                {
                    break; // we timed out
                }
                responses.Add(response.Address, response);

                if (response.Exception != null)
                {
                    exceptions.Add(response.Exception);
                    continue;
                }

                if (response.IsPrimary)
                {
                    primaryConnection = response.Connection;
                    replicaSet        = GetHostAddresses(response);
                    maxDocumentSize   = response.MaxDocumentSize;
                    maxMessageLength  = response.MaxMessageLength;
                    if (!server.Settings.SlaveOk)
                    {
                        break; // if we're not going to use the secondaries no need to wait for their replies
                    }
                }
                else
                {
                    if (server.Settings.SlaveOk)
                    {
                        secondaryConnections.Add(response.Connection);
                    }
                    else
                    {
                        response.Connection.Close();
                    }
                }

                // look for additional members of the replica set that might not have been in the seed list and query them also
                foreach (var address in GetHostAddresses(response))
                {
                    if (!queries.Contains(address))
                    {
                        var args = new QueryNodeParameters {
                            Address       = address,
                            EndPoint      = address.ToIPEndPoint(server.Settings.AddressFamily),
                            ResponseQueue = responsesQueue
                        };
                        ThreadPool.QueueUserWorkItem(QueryNodeWorkItem, args);
                        queries.Add(address);
                    }
                }
            }

            if (primaryConnection == null)
            {
                var innerException = exceptions.FirstOrDefault();
                var exception      = new MongoConnectionException("Unable to connect to server", innerException);
                if (exceptions.Count > 1)
                {
                    exception.Data.Add("InnerExceptions", exceptions);
                }
                throw exception;
            }
        }
 private BlockingQueue<QueryNodeResponse> QueueSeedListQueries() {
     var responseQueue = new BlockingQueue<QueryNodeResponse>();
     var addresses = server.Settings.Servers.ToList();
     var endPoints = server.EndPoints.ToList();
     for (int i = 0; i < addresses.Count; i++) {
         var args = new QueryNodeParameters {
             Address = addresses[i],
             EndPoint = endPoints[i],
             ResponseQueue = responseQueue
         };
         ThreadPool.QueueUserWorkItem(QueryNodeWorkItem, args);
         queries.Add(addresses[i]);
     }
     return responseQueue;
 }
        public void Connect(
            TimeSpan timeout
        ) {
            // query all servers in seed list in parallel (they will report responses back through the responsesQueue)
            var responsesQueue = QueueSeedListQueries();

            // process the responses as they come back and stop as soon as we find the primary (unless SlaveOk is true)
            // stragglers will continue to report responses to the responsesQueue but no one will read them
            // and eventually it will all get garbage collected

            var exceptions = new List<Exception>();
            var timeoutAt = DateTime.UtcNow + timeout;
            while (responses.Count < queries.Count) {
                var timeRemaining = timeoutAt - DateTime.UtcNow;
                var response = responsesQueue.Dequeue(timeRemaining);
                if (response == null) {
                    break; // we timed out
                }
                responses.Add(response.Address, response);

                if (response.Exception != null) {
                    exceptions.Add(response.Exception);
                    continue;
                }

                if (response.IsPrimary) {
                    primaryConnection = response.Connection;
                    replicaSet = GetHostAddresses(response);
                    maxDocumentSize = response.MaxDocumentSize;
                    maxMessageLength = response.MaxMessageLength;
                    if (!server.Settings.SlaveOk) {
                        break; // if we're not going to use the secondaries no need to wait for their replies
                    }
                } else {
                    if (server.Settings.SlaveOk) {
                        secondaryConnections.Add(response.Connection);
                    } else {
                        response.Connection.Close();
                    }
                }

                // look for additional members of the replica set that might not have been in the seed list and query them also
                foreach (var address in GetHostAddresses(response)) {
                    if (!queries.Contains(address)) {
                        var args = new QueryNodeParameters {
                            Address = address,
                            EndPoint = address.ToIPEndPoint(server.Settings.AddressFamily),
                            ResponseQueue = responsesQueue
                        };
                        ThreadPool.QueueUserWorkItem(QueryNodeWorkItem, args);
                        queries.Add(address);
                    }
                }
            }

            if (primaryConnection == null) {
                var innerException = exceptions.FirstOrDefault();
                var exception = new MongoConnectionException("Unable to connect to server", innerException);
                if (exceptions.Count > 1) {
                    exception.Data.Add("InnerExceptions", exceptions);
                }
                throw exception;
            }
        }
 private BlockingQueue<QueryNodeResponse> QuerySeedListNodes()
 {
     var responseQueue = new BlockingQueue<QueryNodeResponse>();
     foreach (var address in url.Servers) {
         var args = new QueryNodeParameters {
             Address = address,
             ResponseQueue = responseQueue
         };
         ThreadPool.QueueUserWorkItem(QueryNodeWorkItem, args);
         queries.Add(address);
     }
     return responseQueue;
 }