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')
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
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
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
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
def parse_ismaster_response(doc): ismaster_response = Hello(doc) return ServerDescription(address, ismaster_response)
def got_hello(topology, server_address, hello_response): server_description = ServerDescription( server_address, Hello(hello_response), 0) topology.on_change(server_description)
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))
def _check_with_socket(self, *args, **kwargs): if isinstance(responses[1], Exception): raise responses[1] return Hello(responses[1]), 99
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)