def apply_selector(self, selector, address=None, custom_selector=None): """List of servers matching the provided selector(s). :Parameters: - `selector`: a callable that takes a Selection as input and returns a Selection as output. For example, an instance of a read preference from :mod:`~pymongo.read_preferences`. - `address` (optional): A server address to select. - `custom_selector` (optional): A callable that augments server selection rules. Accepts a list of :class:`~pymongo.server_description.ServerDescription` objects and return a list of server descriptions that should be considered suitable for the desired operation. .. versionadded:: 3.4 """ if getattr(selector, 'min_wire_version', 0): common_wv = self.common_wire_version if common_wv and common_wv < selector.min_wire_version: raise ConfigurationError( "%s requires min wire version %d, but topology's min" " wire version is %d" % (selector, selector.min_wire_version, common_wv)) if self.topology_type == TOPOLOGY_TYPE.Unknown: return [] elif self.topology_type in (TOPOLOGY_TYPE.Single, TOPOLOGY_TYPE.LoadBalanced): # Ignore selectors for standalone and load balancer mode. return self.known_servers elif address: # Ignore selectors when explicit address is requested. description = self.server_descriptions().get(address) return [description] if description else [] elif self.topology_type == TOPOLOGY_TYPE.Sharded: # Ignore read preference. selection = Selection.from_topology_description(self) else: selection = selector(Selection.from_topology_description(self)) # Apply custom selector followed by localThresholdMS. if custom_selector is not None and selection: selection = selection.with_server_descriptions( custom_selector(selection.server_descriptions)) return self._apply_local_threshold(selection)
def test_bool(self): client = single_client() wait_until(lambda: client.address, "discover primary") selection = Selection.from_topology_description( client._topology.description) self.assertTrue(selection) self.assertFalse(selection.with_server_descriptions([]))
def apply_selector(self, selector, address, custom_selector=None): def apply_local_threshold(selection): if not selection: return [] settings = self._topology_settings # Round trip time in seconds. fastest = min( s.round_trip_time for s in selection.server_descriptions) threshold = settings.local_threshold_ms / 1000.0 return [s for s in selection.server_descriptions if (s.round_trip_time - fastest) <= threshold] if getattr(selector, 'min_wire_version', 0): common_wv = self.common_wire_version if common_wv and common_wv < selector.min_wire_version: raise ConfigurationError( "%s requires min wire version %d, but topology's min" " wire version is %d" % (selector, selector.min_wire_version, common_wv)) if self.topology_type in (TOPOLOGY_TYPE.Single, TOPOLOGY_TYPE.LoadBalanced): # Ignore selectors for standalone and load balancer mode. return self.known_servers elif address: # Ignore selectors when explicit address is requested. description = self.server_descriptions().get(address) return [description] if description else [] elif self.topology_type == TOPOLOGY_TYPE.Sharded: # Ignore read preference. selection = Selection.from_topology_description(self) else: selection = selector(Selection.from_topology_description(self)) # Apply custom selector followed by localThresholdMS. if custom_selector is not None and selection: selection = selection.with_server_descriptions( custom_selector(selection.server_descriptions)) return apply_local_threshold(selection)
def apply_selector(self, selector, address): def apply_local_threshold(selection): if not selection: return [] settings = self._topology_settings # Round trip time in seconds. fastest = min( s.round_trip_time for s in selection.server_descriptions) threshold = settings.local_threshold_ms / 1000.0 return [s for s in selection.server_descriptions if (s.round_trip_time - fastest) <= threshold] if getattr(selector, 'min_wire_version', 0): common_wv = self.common_wire_version if common_wv and common_wv < selector.min_wire_version: raise ConfigurationError( "%s requires min wire version %d, but topology's min" " wire version is %d" % (selector, selector.min_wire_version, common_wv)) if self.topology_type == TOPOLOGY_TYPE.Single: # Ignore the selector. return self.known_servers elif address: description = self.server_descriptions().get(address) return [description] if description else [] elif self.topology_type == TOPOLOGY_TYPE.Sharded: # Ignore the read preference, but apply localThresholdMS. return apply_local_threshold( Selection.from_topology_description(self)) else: return apply_local_threshold( selector(Selection.from_topology_description(self)))
def apply_selector(self, selector, address): def apply_local_threshold(selection): if not selection: return [] settings = self._topology_settings # Round trip time in seconds. fastest = min(s.round_trip_time for s in selection.server_descriptions) threshold = settings.local_threshold_ms / 1000.0 return [ s for s in selection.server_descriptions if (s.round_trip_time - fastest) <= threshold ] if getattr(selector, 'min_wire_version', 0): common_wv = self.common_wire_version if common_wv and common_wv < selector.min_wire_version: raise ConfigurationError( "%s requires min wire version %d, but topology's min" " wire version is %d" % (selector, selector.min_wire_version, common_wv)) if self.topology_type == TOPOLOGY_TYPE.Single: # Ignore the selector. return self.known_servers elif address: description = self.server_descriptions().get(address) return [description] if description else [] elif self.topology_type == TOPOLOGY_TYPE.Sharded: # Ignore the read preference, but apply localThresholdMS. return apply_local_threshold( Selection.from_topology_description(self)) else: return apply_local_threshold( selector(Selection.from_topology_description(self)))
def _new_selection(self): """A Selection object, initially including all known servers. Hold the lock when calling this. """ return Selection.from_topology_description(self._description)