PYTHON-926 - ReadPreference.NEAREST shouldn't pick arbiters.
This commit is contained in:
parent
c31d4808bf
commit
f282babff0
@ -21,6 +21,10 @@ def any_server_selector(server_descriptions):
|
||||
return server_descriptions
|
||||
|
||||
|
||||
def readable_server_selector(server_descriptions):
|
||||
return [s for s in server_descriptions if s.is_readable]
|
||||
|
||||
|
||||
def writable_server_selector(server_descriptions):
|
||||
return [s for s in server_descriptions if s.is_writable]
|
||||
|
||||
@ -49,6 +53,11 @@ def single_tag_set_server_selector(tag_set, server_descriptions):
|
||||
A server tagged {'a': '1', 'b': '2'} matches the tag set {'a': '1'}.
|
||||
|
||||
The empty tag set {} matches any server.
|
||||
|
||||
The `server_descriptions` passed to this function should have
|
||||
non-readable servers (e.g. RSGhost, RSArbiter, Unknown) filtered
|
||||
out (e.g. by readable_server_selector or secondary_server_selector)
|
||||
first.
|
||||
"""
|
||||
def tags_match(server_tags):
|
||||
for key, value in tag_set.items():
|
||||
@ -68,6 +77,11 @@ def tag_sets_server_selector(tag_sets, server_descriptions):
|
||||
[{'a': 'value'}, {}] expresses a preference for servers tagged
|
||||
{'a': 'value'}, but accepts any server if none matches the first
|
||||
preference.
|
||||
|
||||
The `server_descriptions` passed to this function should have
|
||||
non-readable servers (e.g. RSGhost, RSArbiter, Unknown) filtered
|
||||
out (e.g. by readable_server_selector or secondary_server_selector)
|
||||
first.
|
||||
"""
|
||||
for tag_set in tag_sets:
|
||||
selected = single_tag_set_server_selector(tag_set, server_descriptions)
|
||||
@ -81,6 +95,11 @@ def apply_local_threshold(latency_ms, server_descriptions):
|
||||
"""All servers with round trip times within latency_ms of the fastest one.
|
||||
|
||||
No ServerDescription's round_trip_time can be None.
|
||||
|
||||
The `server_descriptions` passed to this function should have
|
||||
non-readable servers (e.g. RSGhost, RSArbiter, Unknown) filtered
|
||||
out (e.g. by readable_server_selector or secondary_server_selector)
|
||||
first.
|
||||
"""
|
||||
if not server_descriptions:
|
||||
# Avoid ValueError from min() with empty sequence.
|
||||
@ -104,4 +123,5 @@ def secondary_with_tags_server_selector(tag_sets, server_descriptions):
|
||||
|
||||
def member_with_tags_server_selector(tag_sets, server_descriptions):
|
||||
"""All near-enough members matching the tag sets."""
|
||||
return tag_sets_server_selector(tag_sets, server_descriptions)
|
||||
return tag_sets_server_selector(
|
||||
tag_sets, readable_server_selector(server_descriptions))
|
||||
|
||||
@ -127,8 +127,13 @@ class ClientContext(object):
|
||||
self.rs_client = pymongo.MongoClient(
|
||||
pair, replicaSet=self.replica_set_name)
|
||||
|
||||
self.nodes = set([partition_node(node)
|
||||
for node in self.ismaster.get('hosts', [])])
|
||||
nodes = [partition_node(node)
|
||||
for node in self.ismaster.get('hosts', [])]
|
||||
nodes.extend([partition_node(node)
|
||||
for node in self.ismaster.get('passives', [])])
|
||||
nodes.extend([partition_node(node)
|
||||
for node in self.ismaster.get('arbiters', [])])
|
||||
self.nodes = set(nodes)
|
||||
|
||||
self.rs_or_standalone_client = self.rs_client or self.client
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ from pymongo.read_preferences import (ReadPreference, MovingAverage,
|
||||
Primary, PrimaryPreferred,
|
||||
Secondary, SecondaryPreferred,
|
||||
Nearest, _ServerMode)
|
||||
from pymongo.server_selectors import any_server_selector
|
||||
from pymongo.server_selectors import readable_server_selector
|
||||
from pymongo.server_type import SERVER_TYPE
|
||||
from pymongo.write_concern import WriteConcern
|
||||
|
||||
@ -97,7 +97,7 @@ class TestReadPreferencesBase(TestReplicaSetClientBase):
|
||||
def assertReadsFrom(self, expected, **kwargs):
|
||||
c = rs_client(**kwargs)
|
||||
wait_until(
|
||||
lambda: len(c.nodes) == self.w,
|
||||
lambda: len(c.nodes - c.arbiters) == self.w,
|
||||
"discovered all nodes")
|
||||
|
||||
used = self.read_from_which_kind(c)
|
||||
@ -249,7 +249,8 @@ class TestReadPreferences(TestReadPreferencesBase):
|
||||
latencies = ', '.join(
|
||||
'%s: %dms' % (server.description.address,
|
||||
server.description.round_trip_time)
|
||||
for server in c._get_topology().select_servers(any_server_selector))
|
||||
for server in c._get_topology().select_servers(
|
||||
readable_server_selector))
|
||||
|
||||
self.assertFalse(
|
||||
not_used,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user