Esempio n. 1
0
    def _ensure_opened(self):
        """Start monitors, or restart after a fork.

        Hold the lock when calling this.
        """
        if not self._opened:
            self._opened = True
            self._update_servers()

            # Start or restart the events publishing thread.
            if self._publish_tp or self._publish_server:
                self.__events_executor.open()

            # Start the SRV polling thread.
            if self._srv_monitor and (self.description.topology_type
                                      in SRV_POLLING_TOPOLOGIES):
                self._srv_monitor.open()

            if self._settings.load_balanced:
                # Emit initial SDAM events for load balancer mode.
                self._process_change(
                    ServerDescription(
                        self._seed_addresses[0],
                        Hello({
                            'ok': 1,
                            'serviceId': self._topology_id,
                            'maxWireVersion': 13
                        })))

        # Ensure that the monitors are open.
        for server in self._servers.values():
            server.open()
 def _check_with_socket(self, *args, **kwargs):
     ismaster_count[0] += 1
     if ismaster_count[0] in (1, 3):
         return Hello({'ok': 1, 'maxWireVersion': 6}), 0
     else:
         raise AutoReconnect('mock monitor error #%s' %
                             (ismaster_count[0], ))
 def _check_with_socket(self, *args, **kwargs):
     if available:
         return (Hello({
             'ok': 1,
             'maxWireVersion': 6
         }), round_trip_time)
     else:
         raise AutoReconnect('mock monitor error')
Esempio n. 4
0
def make_server_description(server, hosts):
    """Make a ServerDescription from server info in a JSON test."""
    server_type = server['type']
    if server_type in ("Unknown", "PossiblePrimary"):
        return ServerDescription(clean_node(server['address']), Hello({}))

    hello_response = {'ok': True, 'hosts': hosts}
    if server_type not in ("Standalone", "Mongos", "RSGhost"):
        hello_response['setName'] = "rs"

    if server_type == "RSPrimary":
        hello_response[HelloCompat.LEGACY_CMD] = True
    elif server_type == "RSSecondary":
        hello_response['secondary'] = True
    elif server_type == "Mongos":
        hello_response['msg'] = 'isdbgrid'
    elif server_type == "RSGhost":
        hello_response['isreplicaset'] = True
    elif server_type == "RSArbiter":
        hello_response['arbiterOnly'] = True

    hello_response['lastWrite'] = {
        'lastWriteDate': make_last_write_date(server)
    }

    for field in 'maxWireVersion', 'tags', 'idleWritePeriodMillis':
        if field in server:
            hello_response[field] = server[field]

    hello_response.setdefault('maxWireVersion', 6)

    # Sets _last_update_time to now.
    sd = ServerDescription(clean_node(server['address']),
                           Hello(hello_response),
                           round_trip_time=server['avg_rtt_ms'] / 1000.0)

    if 'lastUpdateTime' in server:
        sd._last_update_time = server['lastUpdateTime'] / 1000.0  # ms to sec.

    return sd
Esempio n. 5
0
    def _run_scenario(self):
        class NoopMonitor(Monitor):
            """Override the _run method to do nothing."""
            def _run(self):
                time.sleep(0.05)

        m = single_client(h=scenario_def['uri'], p=27017,
                          event_listeners=[self.all_listener],
                          _monitor_class=NoopMonitor)
        topology = m._get_topology()

        try:
            for phase in scenario_def['phases']:
                for (source, response) in phase.get('responses', []):
                    source_address = clean_node(source)
                    topology.on_change(ServerDescription(
                        address=source_address,
                        ismaster=Hello(response),
                        round_trip_time=0))

                expected_results = phase['outcome']['events']
                expected_len = len(expected_results)
                wait_until(
                    lambda: len(self.all_listener.results) >= expected_len,
                    "publish all events", timeout=15)

                # Wait some time to catch possible lagging extra events.
                time.sleep(0.5)

                i = 0
                while i < expected_len:
                    result = self.all_listener.results[i] if len(
                        self.all_listener.results) > i else None
                    # The order of ServerOpening/ClosedEvents doesn't matter
                    if isinstance(result, (monitoring.ServerOpeningEvent,
                                           monitoring.ServerClosedEvent)):
                        i, passed, message = compare_multiple_events(
                            i, expected_results, self.all_listener.results)
                        self.assertTrue(passed, message)
                    else:
                        self.assertTrue(
                            *compare_events(expected_results[i], result))
                        i += 1

                # Assert no extra events.
                extra_events = self.all_listener.results[expected_len:]
                if extra_events:
                    self.fail('Extra events %r' % (extra_events,))

                self.all_listener.reset()
        finally:
            m.close()
    def __init__(
        self,
        address: _Address,
        hello: Optional[Hello] = None,
        round_trip_time: Optional[float] = None,
        error: Optional[Exception] = None,
    ) -> None:
        self._address = address
        if not hello:
            hello = Hello({})

        self._server_type = hello.server_type
        self._all_hosts = hello.all_hosts
        self._tags = hello.tags
        self._replica_set_name = hello.replica_set_name
        self._primary = hello.primary
        self._max_bson_size = hello.max_bson_size
        self._max_message_size = hello.max_message_size
        self._max_write_batch_size = hello.max_write_batch_size
        self._min_wire_version = hello.min_wire_version
        self._max_wire_version = hello.max_wire_version
        self._set_version = hello.set_version
        self._election_id = hello.election_id
        self._cluster_time = hello.cluster_time
        self._is_writable = hello.is_writable
        self._is_readable = hello.is_readable
        self._ls_timeout_minutes = hello.logical_session_timeout_minutes
        self._round_trip_time = round_trip_time
        self._me = hello.me
        self._last_update_time = time.monotonic()
        self._error = error
        self._topology_version = hello.topology_version
        if error:
            details = getattr(error, "details", None)
            if isinstance(details, dict):
                self._topology_version = details.get("topologyVersion")

        self._last_write_date: Optional[float]
        if hello.last_write_date:
            # Convert from datetime to seconds.
            delta = hello.last_write_date - EPOCH_NAIVE
            self._last_write_date = delta.total_seconds()
        else:
            self._last_write_date = None
Esempio n. 7
0
    def _check_with_socket(self, conn):
        """Return (Hello, round_trip_time).

        Can raise ConnectionFailure or OperationFailure.
        """
        cluster_time = self._topology.max_cluster_time()
        start = time.monotonic()
        if conn.more_to_come:
            # Read the next streaming isMaster (MongoDB 4.4+).
            response = Hello(conn._next_reply(), awaitable=True)
        elif (conn.performed_handshake
              and self._server_description.topology_version):
            # Initiate streaming isMaster (MongoDB 4.4+).
            response = conn._ismaster(
                cluster_time, self._server_description.topology_version,
                self._settings.heartbeat_frequency, None)
        else:
            # New connection handshake or polling isMaster (MongoDB <4.4).
            response = conn._ismaster(cluster_time, None, None, None)
        return response, time.monotonic() - start
Esempio n. 8
0
    def __init__(self,
                 address,
                 ismaster=None,
                 round_trip_time=None,
                 error=None):
        self._address = address
        if not ismaster:
            ismaster = Hello({})

        self._server_type = ismaster.server_type
        self._all_hosts = ismaster.all_hosts
        self._tags = ismaster.tags
        self._replica_set_name = ismaster.replica_set_name
        self._primary = ismaster.primary
        self._max_bson_size = ismaster.max_bson_size
        self._max_message_size = ismaster.max_message_size
        self._max_write_batch_size = ismaster.max_write_batch_size
        self._min_wire_version = ismaster.min_wire_version
        self._max_wire_version = ismaster.max_wire_version
        self._set_version = ismaster.set_version
        self._election_id = ismaster.election_id
        self._cluster_time = ismaster.cluster_time
        self._is_writable = ismaster.is_writable
        self._is_readable = ismaster.is_readable
        self._ls_timeout_minutes = ismaster.logical_session_timeout_minutes
        self._round_trip_time = round_trip_time
        self._me = ismaster.me
        self._last_update_time = time.monotonic()
        self._error = error
        self._topology_version = ismaster.topology_version
        if error:
            if hasattr(error, 'details') and isinstance(error.details, dict):
                self._topology_version = error.details.get('topologyVersion')

        if ismaster.last_write_date:
            # Convert from datetime to seconds.
            delta = ismaster.last_write_date - EPOCH_NAIVE
            self._last_write_date = delta.total_seconds()
        else:
            self._last_write_date = None
Esempio n. 9
0
def parse_ismaster_response(doc):
    ismaster_response = Hello(doc)
    return ServerDescription(address, ismaster_response)
Esempio n. 10
0
def got_hello(topology, server_address, hello_response):
    server_description = ServerDescription(
        server_address, Hello(hello_response), 0)
    topology.on_change(server_description)
Esempio n. 11
0
 def test_repr(self):
     ismaster = Hello({'ok': 1})
     sd = ServerDescription(('localhost', 27017), ismaster)
     server = Server(sd, pool=object(), monitor=object())
     self.assertTrue('Standalone' in str(server))
Esempio n. 12
0
 def _check_with_socket(self, *args, **kwargs):
     if isinstance(responses[1], Exception):
         raise responses[1]
     return Hello(responses[1]), 99
Esempio n. 13
0
def parse_hello_response(doc):
    hello_response = Hello(doc)
    return ServerDescription(address, hello_response)
def got_ismaster(topology, server_address, ismaster_response):
    server_description = ServerDescription(server_address,
                                           Hello(ismaster_response), 0)
    topology.on_change(server_description)
 def _check_once(self):
     client = self.client
     address = self._server_description.address
     response, rtt = client.mock_is_master('%s:%d' % address)
     return ServerDescription(address, Hello(response), rtt)