Python pymongo.errors.ServerSelectionTimeoutError() Examples

The following are 30 code examples of pymongo.errors.ServerSelectionTimeoutError(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module pymongo.errors , or try the search function .
Example #1
Source Project: vnpy_crypto   Author: birforce   File: topology.py    License: MIT License 7 votes vote down vote up
def select_server_by_address(self, address,
                                 server_selection_timeout=None):
        """Return a Server for "address", reconnecting if necessary.

        If the server's type is not known, request an immediate check of all
        servers. Time out after "server_selection_timeout" if the server
        cannot be reached.

        :Parameters:
          - `address`: A (host, port) pair.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value
            common.SERVER_SELECTION_TIMEOUT is used.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        """
        return self.select_server(any_server_selector,
                                  server_selection_timeout,
                                  address) 
Example #2
Source Project: ansible-role-mongodb   Author: UnderGreen   File: mongodb_replication.py    License: GNU General Public License v2.0 6 votes vote down vote up
def wait_for_ok_and_master(module, connection_params, timeout = 180):
    start_time = dtdatetime.now()
    while True:
        try:
            client = MongoClient(**connection_params)
            authenticate(client, connection_params["username"], connection_params["password"])

            status = client.admin.command('replSetGetStatus', check=False)
            if status['ok'] == 1 and status['myState'] == 1:
                return

        except ServerSelectionTimeoutError:
            pass

        client.close()

        if (dtdatetime.now() - start_time).seconds > timeout:
            module.fail_json(msg='reached timeout while waiting for rs.status() to become ok=1')

        time.sleep(1) 
Example #3
Source Project: satori   Author: leancloud   File: topology.py    License: Apache License 2.0 6 votes vote down vote up
def select_server_by_address(self, address,
                                 server_selection_timeout=None):
        """Return a Server for "address", reconnecting if necessary.

        If the server's type is not known, request an immediate check of all
        servers. Time out after "server_selection_timeout" if the server
        cannot be reached.

        :Parameters:
          - `address`: A (host, port) pair.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value
            common.SERVER_SELECTION_TIMEOUT is used.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        """
        return self.select_server(any_server_selector,
                                  server_selection_timeout,
                                  address) 
Example #4
Source Project: learn_python3_spider   Author: wistbean   File: topology.py    License: MIT License 6 votes vote down vote up
def select_server_by_address(self, address,
                                 server_selection_timeout=None):
        """Return a Server for "address", reconnecting if necessary.

        If the server's type is not known, request an immediate check of all
        servers. Time out after "server_selection_timeout" if the server
        cannot be reached.

        :Parameters:
          - `address`: A (host, port) pair.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value
            common.SERVER_SELECTION_TIMEOUT is used.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        """
        return self.select_server(any_server_selector,
                                  server_selection_timeout,
                                  address) 
Example #5
Source Project: Astra   Author: flipkart-incubator   File: dbconnection.py    License: Apache License 2.0 6 votes vote down vote up
def db_connect():
    maxSevSelDelay = 1
    try:
        mongo_host = 'localhost'
        mongo_port = 27017

        if 'MONGO_PORT_27017_TCP_ADDR' in os.environ :
            mongo_host = os.environ['MONGO_PORT_27017_TCP_ADDR']

        if 'MONGO_PORT_27017_TCP_PORT' in os.environ:
            mongo_port = int(os.environ['MONGO_PORT_27017_TCP_PORT'])

        client = MongoClient(mongo_host, mongo_port, serverSelectionTimeoutMS=maxSevSelDelay)
        client.server_info()
        return client

    except ServerSelectionTimeoutError as err:
        exit("Failed to connect to MongoDB.") 
Example #6
Source Project: ChatterBot   Author: gunthercox   File: test_mongo_adapter.py    License: BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def setUpClass(cls):
        """
        Instantiate the adapter before any tests in the test case run.
        """
        from pymongo.errors import ServerSelectionTimeoutError
        from pymongo import MongoClient

        cls.has_mongo_connection = False

        try:
            client = MongoClient(
                serverSelectionTimeoutMS=0.1
            )
            client.server_info()

            cls.adapter = MongoDatabaseAdapter(
                database_uri='mongodb://localhost:27017/chatterbot_test_database'
            )

            cls.has_mongo_connection = True

        except ServerSelectionTimeoutError:
            pass 
Example #7
Source Project: apex-sigma-core   Author: lu-ci   File: sigma.py    License: GNU General Public License v3.0 6 votes vote down vote up
def init_database(self):
        """
        Initializes the database connection to MongoDB.
        Also pre-caches potentially heavy resources from the DB.
        :return:
        """
        self.log.info('Connecting to Database...')
        self.db = Database(self, self.cfg.db)
        try:
            await self.db[self.db.db_nam].collection.find_one({})
            if self.cfg.cache.type not in ['redis', 'mixed']:
                await self.db.precache_settings()
                await self.db.precache_profiles()
                await self.db.precache_resources()
            set_color_cache_coll(self.db[self.db.db_nam].ColorCache)
        except ServerSelectionTimeoutError:
            self.log.error('A Connection To The Database Host Failed!')
            exit(errno.ETIMEDOUT)
        except OperationFailure:
            self.log.error('Database Access Operation Failed!')
            exit(errno.EACCES)
        self.log.info('Successfully Connected to Database') 
Example #8
Source Project: opsbro   Author: naparuba   File: topology.py    License: MIT License 6 votes vote down vote up
def select_server_by_address(self, address,
                                 server_selection_timeout=None):
        """Return a Server for "address", reconnecting if necessary.

        If the server's type is not known, request an immediate check of all
        servers. Time out after "server_selection_timeout" if the server
        cannot be reached.

        :Parameters:
          - `address`: A (host, port) pair.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value
            common.SERVER_SELECTION_TIMEOUT is used.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        """
        return self.select_server(any_server_selector,
                                  server_selection_timeout,
                                  address) 
Example #9
Source Project: mongo-rs-controller-swarm   Author: smartsdk   File: replica_ctrl.py    License: Apache License 2.0 6 votes vote down vote up
def gather_configured_members_ips(mongo_tasks_ips, mongo_port):
    current_ips = set()
    logger = logging.getLogger(__name__)
    for t in mongo_tasks_ips:
        mc = pm.MongoClient(t, mongo_port)
        try:
            config = mc.admin.command("replSetGetConfig")['config']
            for m in config['members']:
                current_ips.add(m['host'].split(":")[0])
            # Let's accept the first configuration found. Read as room for improvement!
            break
        except ServerSelectionTimeoutError as ssete:
            logger.debug("cannot connect to {} to get configuration, failed ({})".format(t,ssete))
        except OperationFailure as of:
            logger.debug("no configuration found in node {} ({})".format(t,of))
        finally:
            mc.close()
    logger.debug("Current members in mongo configurations: {}".format(current_ips))
    return current_ips 
Example #10
Source Project: mongo-rs-controller-swarm   Author: smartsdk   File: replica_ctrl.py    License: Apache License 2.0 6 votes vote down vote up
def get_primary_ip(tasks_ips, mongo_port):
    logger = logging.getLogger(__name__)

    primary_ips = []
    for t in tasks_ips:
        mc = pm.MongoClient(t, mongo_port)
        try:
            if mc.is_primary:
                primary_ips.append(t)
        except ServerSelectionTimeoutError as ssete:
            logger.debug("cannot connect to {} check if primary, failed ({})".format(t,ssete))
        except OperationFailure as of:
            logger.debug("no configuration found in node {} ({})".format(t,of))
        finally:
            mc.close()

    if len(primary_ips) > 1:
        logger.warning("Multiple primaries were found ({}). Let's use the first.".format(primary_ips))

    if primary_ips:
        logger.info("Primary is: {}".format(primary_ips[0]))
        return primary_ips[0] 
Example #11
Source Project: arctic   Author: man-group   File: test_decorators_unit.py    License: GNU Lesser General Public License v2.1 5 votes vote down vote up
def test_ServerSelectionTimeoutError_no_retry():
    error = ServerSelectionTimeoutError('some error')
    with patch('arctic.decorators._log_exception', autospec=True) as le:
        @mongo_retry
        def foo():
            raise error
        with pytest.raises(ServerSelectionTimeoutError) as e:
            foo()
    assert 'some error' in str(e.value)
    assert le.call_count == 1 
Example #12
Source Project: vnpy_crypto   Author: birforce   File: topology.py    License: MIT License 5 votes vote down vote up
def select_servers(self,
                       selector,
                       server_selection_timeout=None,
                       address=None):
        """Return a list of Servers matching selector, or time out.

        :Parameters:
          - `selector`: function that takes a list of Servers and returns
            a subset of them.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value common.SERVER_SELECTION_TIMEOUT
            is used.
          - `address`: optional server address to select.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        """
        if server_selection_timeout is None:
            server_timeout = self._settings.server_selection_timeout
        else:
            server_timeout = server_selection_timeout

        with self._lock:
            server_descriptions = self._select_servers_loop(
                selector, server_timeout, address)

            return [self.get_server_by_address(sd.address)
                    for sd in server_descriptions] 
Example #13
Source Project: vnpy_crypto   Author: birforce   File: topology.py    License: MIT License 5 votes vote down vote up
def _select_servers_loop(self, selector, timeout, address):
        """select_servers() guts. Hold the lock when calling this."""
        now = _time()
        end_time = now + timeout
        server_descriptions = self._description.apply_selector(
            selector, address)

        while not server_descriptions:
            # No suitable servers.
            if timeout == 0 or now > end_time:
                raise ServerSelectionTimeoutError(
                    self._error_message(selector))

            self._ensure_opened()
            self._request_check_all()

            # Release the lock and wait for the topology description to
            # change, or for a timeout. We won't miss any changes that
            # came after our most recent apply_selector call, since we've
            # held the lock until now.
            self._condition.wait(common.MIN_HEARTBEAT_INTERVAL)
            self._description.check_compatible()
            now = _time()
            server_descriptions = self._description.apply_selector(
                selector, address)

        self._description.check_compatible()
        return server_descriptions 
Example #14
Source Project: mongodb_consistent_backup   Author: Percona-Lab   File: DB.py    License: Apache License 2.0 5 votes vote down vote up
def connect(self):
        try:
            logging.debug("Getting MongoDB connection to %s (replicaSet=%s, readPreference=%s, readPreferenceTags=%s, ssl=%s)" % (
                self.uri,
                self.replset,
                self.read_pref,
                self.do_rp_tags,
                self.do_ssl(),
            ))
            conn = MongoClient(**self.client_opts())
            if self.do_connect:
                conn['admin'].command({"ping": 1})
        except (ConfigurationError, ConnectionFailure, OperationFailure, ServerSelectionTimeoutError), e:
            logging.error("Unable to connect to %s! Error: %s" % (self.uri, e))
            raise DBConnectionError(e) 
Example #15
Source Project: s3recon   Author: clarketm   File: mongodb.py    License: MIT License 5 votes vote down vote up
def is_connected(self):
        try:
            self.client.server_info()
        except ServerSelectionTimeoutError:
            return False
        return True 
Example #16
Source Project: yeti   Author: yeti-platform   File: yeti_to_elasticsearch.py    License: Apache License 2.0 5 votes vote down vote up
def create_mongo_connection(self, hostname="localhost"):
        """
            Creates a connection to YETI's MongoDB.
        :param hostname: Hostname to connect to. Default is "localhost"
        :return: None
        """

        try:
            # Try connecting to MongoDB for 10ms
            self.mongo_client = MongoClient('mongodb://{}:27017/'.format(hostname), serverSelectionTimeoutMS=10)
            self.mongo_client.server_info()
        except errors.ServerSelectionTimeoutError as mongo_conn_err:
            logger.exception(("MongoDB connection issue occurred. "
                              "Error message: " + str(mongo_conn_err)))
            sys.exit(1) 
Example #17
Source Project: evernote-telegram-bot   Author: djudman   File: test_mongo.py    License: MIT License 5 votes vote down vote up
def setUp(self):
        self.db_name = 'test_mongo_storage'
        connection_string = 'mongodb://127.0.0.1:27017/?serverSelectionTimeoutMS=100'
        try:
            self.client = Mongo(connection_string, db_name=self.db_name,
                                collection='test')
            list(self.client.get_all({}))
        except ServerSelectionTimeoutError as e:
            raise SkipTest(str(e)) 
Example #18
Source Project: learn_python3_spider   Author: wistbean   File: topology.py    License: MIT License 5 votes vote down vote up
def select_servers(self,
                       selector,
                       server_selection_timeout=None,
                       address=None):
        """Return a list of Servers matching selector, or time out.

        :Parameters:
          - `selector`: function that takes a list of Servers and returns
            a subset of them.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value common.SERVER_SELECTION_TIMEOUT
            is used.
          - `address`: optional server address to select.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        """
        if server_selection_timeout is None:
            server_timeout = self._settings.server_selection_timeout
        else:
            server_timeout = server_selection_timeout

        with self._lock:
            server_descriptions = self._select_servers_loop(
                selector, server_timeout, address)

            return [self.get_server_by_address(sd.address)
                    for sd in server_descriptions] 
Example #19
Source Project: learn_python3_spider   Author: wistbean   File: topology.py    License: MIT License 5 votes vote down vote up
def _select_servers_loop(self, selector, timeout, address):
        """select_servers() guts. Hold the lock when calling this."""
        now = _time()
        end_time = now + timeout
        server_descriptions = self._description.apply_selector(
            selector, address, custom_selector=self._settings.server_selector)

        while not server_descriptions:
            # No suitable servers.
            if timeout == 0 or now > end_time:
                raise ServerSelectionTimeoutError(
                    self._error_message(selector))

            self._ensure_opened()
            self._request_check_all()

            # Release the lock and wait for the topology description to
            # change, or for a timeout. We won't miss any changes that
            # came after our most recent apply_selector call, since we've
            # held the lock until now.
            self._condition.wait(common.MIN_HEARTBEAT_INTERVAL)
            self._description.check_compatible()
            now = _time()
            server_descriptions = self._description.apply_selector(
                selector, address,
                custom_selector=self._settings.server_selector)

        self._description.check_compatible()
        return server_descriptions 
Example #20
Source Project: ChatterBot   Author: gunthercox   File: base_case.py    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def setUpClass(cls):
        from pymongo.errors import ServerSelectionTimeoutError
        from pymongo import MongoClient

        # Skip these tests if a mongo client is not running
        try:
            client = MongoClient(
                serverSelectionTimeoutMS=0.1
            )
            client.server_info()

        except ServerSelectionTimeoutError:
            raise SkipTest('Unable to connect to Mongo DB.') 
Example #21
Source Project: scout   Author: Clinical-Genomics   File: setup_scout.py    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def setup(context, institute, user_mail, user_name):
    """
    Setup scout instances: a demo database or a production database, according to the
    according to the subcommand specified by user.
    """
    setup_config = {
        "institute_name": institute,
        "user_name": user_name,
        "user_mail": user_mail,
    }

    mongodb_name = current_app.config["MONGO_DBNAME"]
    client = current_app.config["MONGO_CLIENT"]

    if context.invoked_subcommand == "demo":
        # Modify the name of the database that will be created
        LOG.debug("Change database name to scout-demo")
        mongodb_name = "scout-demo"

    mongo_database = client[mongodb_name]
    LOG.info("Test if mongod is running")
    try:
        mongo_database.test.find_one()
    except ServerSelectionTimeoutError as err:
        LOG.warning("Connection could not be established")
        LOG.warning("Please check if mongod is running")
        LOG.warning(err)
        raise click.Abort()

    setup_config["mongodb"] = mongodb_name
    setup_config["adapter"] = MongoAdapter(mongo_database)
    context.obj = setup_config 
Example #22
Source Project: scout   Author: Clinical-Genomics   File: utils.py    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def check_connection(
    host="localhost", port=27017, username=None, password=None, authdb=None, max_delay=1
):
    """Check if a connection could be made to the mongo process specified

    Args:
        host(str)
        port(int)
        username(str)
        password(str)
        authdb (str): database to to for authentication
        max_delay(int): Number of milliseconds to wait for connection

    Returns:
        bool: If connection could be established
    """
    # uri looks like:
    # mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
    if username and password:
        uri = "mongodb://{}:{}@{}:{}/{}".format(
            quote_plus(username), quote_plus(password), host, port, authdb
        )
        log_uri = "mongodb://{}:****@{}:{}/{}".format(quote_plus(username), host, port, authdb)
    else:
        log_uri = uri = "mongodb://%s:%s" % (host, port)

    LOG.info("Test connection with uri: %s", log_uri)
    client = MongoClient(uri, serverSelectionTimeoutMS=max_delay)
    try:
        client.server_info()
    except (ServerSelectionTimeoutError, OperationFailure) as err:
        LOG.warning(err)
        return False

    return True 
Example #23
Source Project: PyChemia   Author: MaterialsDiscovery   File: db.py    License: MIT License 5 votes vote down vote up
def has_connection(host='localhost'):
    if not HAS_PYMONGO:
        return False
    import pymongo
    try:
        maxSevSelDelay = 2
        client = pymongo.MongoClient(host, serverSelectionTimeoutMS=maxSevSelDelay)
        client.server_info()  # force connection on a request as the
        # connect=True parameter of MongoClient seems
        # to be useless here
        return True
    except pymongo.errors.ServerSelectionTimeoutError as err:
        # do whatever you need
        print(err)
        return False 
Example #24
Source Project: PyChemia   Author: MaterialsDiscovery   File: local_mongo.py    License: MIT License 5 votes vote down vote up
def has_local_mongo():
    try:
        max_server_selection_delay = 1
        client = MongoClient("localhost", serverSelectionTimeoutMS=max_server_selection_delay)
        client.server_info()  # force connection on a request as the
        return True
    except ServerSelectionTimeoutError as err:
        print(err)
        return False 
Example #25
Source Project: cti-taxii-server   Author: oasis-open   File: mongodb_backend.py    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def catch_mongodb_error(func):
    """Catch mongodb availability error"""

    def api_wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except (ConnectionFailure, ServerSelectionTimeoutError) as e:
            raise MongoBackendError("Unable to connect to MongoDB", 500, e)

    return api_wrapper 
Example #26
Source Project: st2   Author: StackStorm   File: test_db.py    License: Apache License 2.0 5 votes vote down vote up
def test_db_connect_server_selection_timeout_ssl_on_non_ssl_listener(self):
        # Verify that the we wait connection_timeout ms (server selection timeout ms) before failing
        # and propagating the error
        disconnect()

        db_name = 'st2'
        db_host = 'localhost'
        db_port = 27017

        cfg.CONF.set_override(name='connection_timeout', group='database', override=1000)

        start = time.time()
        self.assertRaises(ServerSelectionTimeoutError, db_setup, db_name=db_name, db_host=db_host,
                          db_port=db_port, ssl=True)
        end = time.time()
        diff = (end - start)

        self.assertTrue(diff >= 1)

        disconnect()

        cfg.CONF.set_override(name='connection_timeout', group='database', override=400)

        start = time.time()
        self.assertRaises(ServerSelectionTimeoutError, db_setup, db_name=db_name, db_host=db_host,
                          db_port=db_port, ssl=True)
        end = time.time()
        diff = (end - start)

        self.assertTrue(diff >= 0.4) 
Example #27
Source Project: trading-server   Author: s-brez   File: server.py    License: GNU General Public License v3.0 5 votes vote down vote up
def check_db_connection(self):
        """
        Raise exception if DB connection not active.

        Args:
            None.

        Returns:
            None.

        Raises:
            Database connection failure error.
        """

        try:
            time.sleep(self.DB_TIMEOUT_MS)
            self.db_client.server_info()
            self.logger.debug(
                "Connected to " + self.DB_PRICES + " at " +
                self.DB_URL + ".")
        except errors.ServerSelectionTimeoutError as e:
            self.logger.debug(
                "Failed to connect to " + self.DB_PRICES + " at " +
                self.DB_URL + ".")
            raise Exception()

        # TODO: Create indexing if not present. 
Example #28
Source Project: satori   Author: leancloud   File: topology.py    License: Apache License 2.0 4 votes vote down vote up
def select_servers(self,
                       selector,
                       server_selection_timeout=None,
                       address=None):
        """Return a list of Servers matching selector, or time out.

        :Parameters:
          - `selector`: function that takes a list of Servers and returns
            a subset of them.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value common.SERVER_SELECTION_TIMEOUT
            is used.
          - `address`: optional server address to select.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        """
        if server_selection_timeout is None:
            server_timeout = self._settings.server_selection_timeout
        else:
            server_timeout = server_selection_timeout

        with self._lock:
            self._description.check_compatible()

            now = _time()
            end_time = now + server_timeout
            server_descriptions = self._apply_selector(selector, address)

            while not server_descriptions:
                # No suitable servers.
                if server_timeout == 0 or now > end_time:
                    raise ServerSelectionTimeoutError(
                        self._error_message(selector))

                self._ensure_opened()
                self._request_check_all()

                # Release the lock and wait for the topology description to
                # change, or for a timeout. We won't miss any changes that
                # came after our most recent _apply_selector call, since we've
                # held the lock until now.
                self._condition.wait(common.MIN_HEARTBEAT_INTERVAL)
                self._description.check_compatible()
                now = _time()
                server_descriptions = self._apply_selector(selector, address)

            return [self.get_server_by_address(sd.address)
                    for sd in server_descriptions] 
Example #29
Source Project: scout   Author: Clinical-Genomics   File: client.py    License: BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def get_connection(
    host="localhost",
    port=27017,
    username=None,
    password=None,
    uri=None,
    mongodb=None,
    authdb=None,
    timeout=20,
    *args,
    **kwargs
):
    """Get a client to the mongo database

        host(str): Host of database
        port(int): Port of database
        username(str)
        password(str)
        uri(str)
        authdb (str): database to use for authentication
        timeout(int): How long should the client try to connect

    """
    authdb = authdb or mongodb
    if uri is None:
        if username and password:
            uri = "mongodb://{}:{}@{}:{}/{}".format(
                quote_plus(username), quote_plus(password), host, port, authdb
            )
            log_uri = "mongodb://{}:****@{}:{}/{}".format(quote_plus(username), host, port, authdb)
        else:
            log_uri = uri = "mongodb://%s:%s" % (host, port)

    LOG.info("Try to connect to %s" % log_uri)
    try:
        client = MongoClient(uri, serverSelectionTimeoutMS=timeout)
    except ServerSelectionTimeoutError as err:
        LOG.warning("Connection Refused")
        raise ConnectionFailure

    LOG.info("Connection established")
    return client 
Example #30
Source Project: opsbro   Author: naparuba   File: topology.py    License: MIT License 4 votes vote down vote up
def select_servers(self,
                       selector,
                       server_selection_timeout=None,
                       address=None):
        """Return a list of Servers matching selector, or time out.

        :Parameters:
          - `selector`: function that takes a list of Servers and returns
            a subset of them.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value common.SERVER_SELECTION_TIMEOUT
            is used.
          - `address`: optional server address to select.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        """
        if server_selection_timeout is None:
            server_timeout = self._settings.server_selection_timeout
        else:
            server_timeout = server_selection_timeout

        with self._lock:
            self._description.check_compatible()

            now = _time()
            end_time = now + server_timeout
            server_descriptions = self._description.apply_selector(
                selector, address)

            while not server_descriptions:
                # No suitable servers.
                if server_timeout == 0 or now > end_time:
                    raise ServerSelectionTimeoutError(
                        self._error_message(selector))

                self._ensure_opened()
                self._request_check_all()

                # Release the lock and wait for the topology description to
                # change, or for a timeout. We won't miss any changes that
                # came after our most recent apply_selector call, since we've
                # held the lock until now.
                self._condition.wait(common.MIN_HEARTBEAT_INTERVAL)
                self._description.check_compatible()
                now = _time()
                server_descriptions = self._description.apply_selector(
                    selector, address)

            return [self.get_server_by_address(sd.address)
                    for sd in server_descriptions]