Skip to content

Commit a2937aa

Browse files
ShaneHarveyajdavis
authored andcommitted
Revert "Pin transactions to a single server address"
This reverts commit 25bc085.
1 parent c6488c1 commit a2937aa

File tree

6 files changed

+42
-72
lines changed

6 files changed

+42
-72
lines changed

pymongo/bulk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ def execute(self, write_concern, session):
427427

428428
client = self.collection.database.client
429429
if not write_concern.acknowledged:
430-
with client._socket_for_writes(session) as sock_info:
430+
with client._socket_for_writes() as sock_info:
431431
self.execute_no_results(sock_info, generator)
432432
else:
433433
return self.execute_command(generator, write_concern, session)

pymongo/client_session.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,13 +319,6 @@ def in_transaction(self):
319319
"""True if this session has an active multi-statement transaction."""
320320
return self._transaction is not None
321321

322-
def _pin_server_address(self, address):
323-
assert self._transaction.address is None, "Transaction already pinned"
324-
self._transaction.address = address
325-
326-
def _pinned_server_address(self):
327-
return self._transaction.address
328-
329322
def _apply_to(self, command, is_retryable, read_preference):
330323
self._check_ended()
331324

pymongo/collection.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -184,16 +184,14 @@ def __init__(self, database, name, create=False, codec_options=None,
184184
unicode_decode_error_handler='replace',
185185
document_class=dict)
186186

187-
def _socket_for_reads(self, session):
188-
return self.__database.client._socket_for_reads(
189-
self.read_preference, session)
187+
def _socket_for_reads(self):
188+
return self.__database.client._socket_for_reads(self.read_preference)
190189

191-
def _socket_for_primary_reads(self, session):
192-
return self.__database.client._socket_for_reads(
193-
ReadPreference.PRIMARY, session)
190+
def _socket_for_primary_reads(self):
191+
return self.__database.client._socket_for_reads(ReadPreference.PRIMARY)
194192

195-
def _socket_for_writes(self, session):
196-
return self.__database.client._socket_for_writes(session)
193+
def _socket_for_writes(self):
194+
return self.__database.client._socket_for_writes()
197195

198196
def _command(self, sock_info, command, slave_ok=False,
199197
read_preference=None,
@@ -254,7 +252,7 @@ def __create(self, options, collation, session):
254252
if "size" in options:
255253
options["size"] = float(options["size"])
256254
cmd.update(options)
257-
with self._socket_for_writes(session) as sock_info:
255+
with self._socket_for_writes() as sock_info:
258256
self._command(
259257
sock_info, cmd, read_preference=ReadPreference.PRIMARY,
260258
write_concern=self.write_concern,
@@ -581,7 +579,7 @@ def _insert_command(session, sock_info, retryable_write):
581579
True, _insert_command, session)
582580
_check_write_command_response(result)
583581
else:
584-
with self._socket_for_writes(session=None) as sock_info:
582+
with self._socket_for_writes() as sock_info:
585583
# Legacy OP_INSERT.
586584
self._legacy_write(
587585
sock_info, 'insert', command, op_id,
@@ -1495,7 +1493,7 @@ def parallel_scan(self, num_cursors, session=None, **kwargs):
14951493
('numCursors', num_cursors)])
14961494
cmd.update(kwargs)
14971495

1498-
with self._socket_for_reads(session) as (sock_info, slave_ok):
1496+
with self._socket_for_reads() as (sock_info, slave_ok):
14991497
result = self._command(sock_info, cmd, slave_ok,
15001498
read_concern=self.read_concern,
15011499
session=session)
@@ -1511,7 +1509,7 @@ def parallel_scan(self, num_cursors, session=None, **kwargs):
15111509

15121510
def _count(self, cmd, collation=None, session=None):
15131511
"""Internal count helper."""
1514-
with self._socket_for_reads(session) as (sock_info, slave_ok):
1512+
with self._socket_for_reads() as (sock_info, slave_ok):
15151513
res = self._command(
15161514
sock_info, cmd, slave_ok,
15171515
allowable_errors=["ns missing"],
@@ -1608,7 +1606,7 @@ def create_indexes(self, indexes, session=None, **kwargs):
16081606
"""
16091607
common.validate_list('indexes', indexes)
16101608
names = []
1611-
with self._socket_for_writes(session) as sock_info:
1609+
with self._socket_for_writes() as sock_info:
16121610
supports_collations = sock_info.max_wire_version >= 5
16131611
def gen_indexes():
16141612
for index in indexes:
@@ -1649,7 +1647,7 @@ def __create_index(self, keys, index_options, session, **kwargs):
16491647
index_options.pop('collation', None))
16501648
index.update(index_options)
16511649

1652-
with self._socket_for_writes(session) as sock_info:
1650+
with self._socket_for_writes() as sock_info:
16531651
if collation is not None:
16541652
if sock_info.max_wire_version < 5:
16551653
raise ConfigurationError(
@@ -1876,7 +1874,7 @@ def drop_index(self, index_or_name, session=None, **kwargs):
18761874
self.__database.name, self.__name, name)
18771875
cmd = SON([("dropIndexes", self.__name), ("index", name)])
18781876
cmd.update(kwargs)
1879-
with self._socket_for_writes(session) as sock_info:
1877+
with self._socket_for_writes() as sock_info:
18801878
self._command(sock_info,
18811879
cmd,
18821880
read_preference=ReadPreference.PRIMARY,
@@ -1913,7 +1911,7 @@ def reindex(self, session=None, **kwargs):
19131911
"""
19141912
cmd = SON([("reIndex", self.__name)])
19151913
cmd.update(kwargs)
1916-
with self._socket_for_writes(session) as sock_info:
1914+
with self._socket_for_writes() as sock_info:
19171915
return self._command(
19181916
sock_info, cmd, read_preference=ReadPreference.PRIMARY,
19191917
parse_write_concern_error=True, session=session)
@@ -1942,7 +1940,7 @@ def list_indexes(self, session=None):
19421940
codec_options = CodecOptions(SON)
19431941
coll = self.with_options(codec_options=codec_options,
19441942
read_preference=ReadPreference.PRIMARY)
1945-
with self._socket_for_primary_reads(session) as (sock_info, slave_ok):
1943+
with self._socket_for_primary_reads() as (sock_info, slave_ok):
19461944
cmd = SON([("listIndexes", self.__name), ("cursor", {})])
19471945
if sock_info.max_wire_version > 2:
19481946
with self.__database.client._tmp_session(session, False) as s:
@@ -2063,7 +2061,7 @@ def _aggregate(self, pipeline, cursor_class, first_batch_size, session,
20632061
"batchSize", kwargs.pop("batchSize", None))
20642062
# If the server does not support the "cursor" option we
20652063
# ignore useCursor and batchSize.
2066-
with self._socket_for_reads(session) as (sock_info, slave_ok):
2064+
with self._socket_for_reads() as (sock_info, slave_ok):
20672065
dollar_out = pipeline and '$out' in pipeline[-1]
20682066
if use_cursor:
20692067
if "cursor" not in kwargs:
@@ -2352,7 +2350,7 @@ def group(self, key, condition, initial, reduce, finalize=None, **kwargs):
23522350
collation = validate_collation_or_none(kwargs.pop('collation', None))
23532351
cmd.update(kwargs)
23542352

2355-
with self._socket_for_reads(session=None) as (sock_info, slave_ok):
2353+
with self._socket_for_reads() as (sock_info, slave_ok):
23562354
return self._command(sock_info, cmd, slave_ok,
23572355
collation=collation)["retval"]
23582356

@@ -2398,7 +2396,7 @@ def rename(self, new_name, session=None, **kwargs):
23982396

23992397
new_name = "%s.%s" % (self.__database.name, new_name)
24002398
cmd = SON([("renameCollection", self.__full_name), ("to", new_name)])
2401-
with self._socket_for_writes(session) as sock_info:
2399+
with self._socket_for_writes() as sock_info:
24022400
with self.__database.client._tmp_session(session) as s:
24032401
if sock_info.max_wire_version >= 5 and self.write_concern:
24042402
cmd['writeConcern'] = self.write_concern.document
@@ -2453,7 +2451,7 @@ def distinct(self, key, filter=None, session=None, **kwargs):
24532451
kwargs["query"] = filter
24542452
collation = validate_collation_or_none(kwargs.pop('collation', None))
24552453
cmd.update(kwargs)
2456-
with self._socket_for_reads(session) as (sock_info, slave_ok):
2454+
with self._socket_for_reads() as (sock_info, slave_ok):
24572455
return self._command(sock_info, cmd, slave_ok,
24582456
read_concern=self.read_concern,
24592457
collation=collation, session=session)["values"]
@@ -2525,7 +2523,7 @@ def map_reduce(self, map, reduce, out, full_response=False, session=None,
25252523
cmd.update(kwargs)
25262524

25272525
inline = 'inline' in cmd['out']
2528-
with self._socket_for_primary_reads(session) as (sock_info, slave_ok):
2526+
with self._socket_for_primary_reads() as (sock_info, slave_ok):
25292527
if (sock_info.max_wire_version >= 5 and self.write_concern and
25302528
not inline):
25312529
cmd['writeConcern'] = self.write_concern.document
@@ -2594,7 +2592,7 @@ def inline_map_reduce(self, map, reduce, full_response=False, session=None,
25942592
("out", {"inline": 1})])
25952593
collation = validate_collation_or_none(kwargs.pop('collation', None))
25962594
cmd.update(kwargs)
2597-
with self._socket_for_reads(session) as (sock_info, slave_ok):
2595+
with self._socket_for_reads() as (sock_info, slave_ok):
25982596
if sock_info.max_wire_version >= 4 and 'readConcern' not in cmd:
25992597
res = self._command(sock_info, cmd, slave_ok,
26002598
read_concern=self.read_concern,

pymongo/database.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -526,8 +526,7 @@ def command(self, command, value=1, check=True,
526526
.. mongodoc:: commands
527527
"""
528528
client = self.__client
529-
with client._socket_for_reads(
530-
read_preference, session) as (sock_info, slave_ok):
529+
with client._socket_for_reads(read_preference) as (sock_info, slave_ok):
531530
return self._command(sock_info, command, slave_ok, value,
532531
check, allowable_errors, read_preference,
533532
codec_options, session=session, **kwargs)
@@ -585,7 +584,7 @@ def list_collections(self, session=None, **kwargs):
585584
.. versionadded:: 3.6
586585
"""
587586
with self.__client._socket_for_reads(
588-
ReadPreference.PRIMARY, session) as (sock_info, slave_okay):
587+
ReadPreference.PRIMARY) as (sock_info, slave_okay):
589588
return self._list_collections(
590589
sock_info, slave_okay, session=session, **kwargs)
591590

@@ -650,7 +649,7 @@ def drop_collection(self, name_or_collection, session=None):
650649
self.__client._purge_index(self.__name, name)
651650

652651
with self.__client._socket_for_reads(
653-
ReadPreference.PRIMARY, session) as (sock_info, slave_ok):
652+
ReadPreference.PRIMARY) as (sock_info, slave_ok):
654653
return self._command(
655654
sock_info, 'drop', slave_ok, _unicode(name),
656655
allowable_errors=['ns not found'],
@@ -731,7 +730,7 @@ def current_op(self, include_all=False, session=None):
731730
Added ``session`` parameter.
732731
"""
733732
cmd = SON([("currentOp", 1), ("$all", include_all)])
734-
with self.__client._socket_for_writes(session) as sock_info:
733+
with self.__client._socket_for_writes() as sock_info:
735734
if sock_info.max_wire_version >= 4:
736735
with self.__client._tmp_session(session) as s:
737736
return sock_info.command("admin", cmd, session=s,

pymongo/mongo_client.py

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -871,8 +871,7 @@ def _end_sessions(self, session_ids):
871871
# Use SocketInfo.command directly to avoid implicitly creating
872872
# another session.
873873
with self._socket_for_reads(
874-
ReadPreference.PRIMARY_PREFERRED,
875-
None) as (sock_info, slave_ok):
874+
ReadPreference.PRIMARY_PREFERRED) as (sock_info, slave_ok):
876875
if not sock_info.supports_sessions:
877876
return
878877

@@ -968,31 +967,13 @@ def _get_socket(self, server):
968967
self.__reset_server(server.description.address)
969968
raise
970969

971-
def _select_server(self, read_preference, session):
972-
topology = self._get_topology()
973-
if session and session.in_transaction:
974-
address = session._pinned_server_address()
975-
if address:
976-
server = topology.select_server_by_address(address)
977-
if not server:
978-
raise AutoReconnect(
979-
'Pinned server %s:%d for transaction no longer'
980-
'available' % address)
981-
return server
982-
983-
server = topology.select_server(read_preference)
984-
session._pin_server_address(server.description.address)
985-
return server
986-
else:
987-
return topology.select_server(read_preference)
988-
989-
def _socket_for_writes(self, session):
990-
return self._get_socket(self._select_server(
991-
ReadPreference.PRIMARY, session))
970+
def _socket_for_writes(self):
971+
server = self._get_topology().select_server(writable_server_selector)
972+
return self._get_socket(server)
992973

993974
@contextlib.contextmanager
994-
def _socket_for_reads(self, read_preference, session):
995-
assert read_preference is not None, "read_preference must not be None"
975+
def _socket_for_reads(self, read_preference):
976+
preference = read_preference or ReadPreference.PRIMARY
996977
# Get a socket for a server matching the read preference, and yield
997978
# sock_info, slave_ok. Server Selection Spec: "slaveOK must be sent to
998979
# mongods with topology type Single. If the server type is Mongos,
@@ -1001,11 +982,10 @@ def _socket_for_reads(self, read_preference, session):
1001982
# Thread safe: if the type is single it cannot change.
1002983
topology = self._get_topology()
1003984
single = topology.description.topology_type == TOPOLOGY_TYPE.Single
1004-
server = self._select_server(read_preference, session)
1005-
985+
server = topology.select_server(read_preference)
1006986
with self._get_socket(server) as sock_info:
1007987
slave_ok = (single and not sock_info.is_mongos) or (
1008-
read_preference != ReadPreference.PRIMARY)
988+
preference != ReadPreference.PRIMARY)
1009989
yield sock_info, slave_ok
1010990

1011991
def _send_message_with_response(self, operation, read_preference=None,
@@ -1025,14 +1005,14 @@ def _send_message_with_response(self, operation, read_preference=None,
10251005
self._kill_cursors_executor.open()
10261006

10271007
topology = self._get_topology()
1028-
session = operation.session
10291008
if address:
10301009
server = topology.select_server_by_address(address)
10311010
if not server:
10321011
raise AutoReconnect('server %s:%d no longer available'
10331012
% address)
10341013
else:
1035-
server = self._select_server(read_preference, session)
1014+
selector = read_preference or writable_server_selector
1015+
server = topology.select_server(selector)
10361016

10371017
# A _Query's slaveOk bit is already set for queries with non-primary
10381018
# read preference. If this is a direct connection to a mongod, override
@@ -1085,7 +1065,8 @@ def is_retrying():
10851065
return bulk.retrying if bulk else retrying
10861066
while True:
10871067
try:
1088-
server = self._select_server(ReadPreference.PRIMARY, session)
1068+
server = self._get_topology().select_server(
1069+
writable_server_selector)
10891070
supports_session = (
10901071
session is not None and
10911072
server.description.retryable_writes_supported)
@@ -1559,7 +1540,7 @@ def drop_database(self, name_or_database, session=None):
15591540

15601541
self._purge_index(name)
15611542
with self._socket_for_reads(
1562-
ReadPreference.PRIMARY, None) as (sock_info, slave_ok):
1543+
ReadPreference.PRIMARY) as (sock_info, slave_ok):
15631544
self[name]._command(
15641545
sock_info,
15651546
"dropDatabase",
@@ -1701,7 +1682,7 @@ def unlock(self, session=None):
17011682
Added ``session`` parameter.
17021683
"""
17031684
cmd = SON([("fsyncUnlock", 1)])
1704-
with self._socket_for_writes(session=None) as sock_info:
1685+
with self._socket_for_writes() as sock_info:
17051686
if sock_info.max_wire_version >= 4:
17061687
try:
17071688
with self._tmp_session(session) as s:

test/test_read_preferences.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,8 @@ def __init__(self, *args, **kwargs):
315315
super(ReadPrefTester, self).__init__(*args, **client_options)
316316

317317
@contextlib.contextmanager
318-
def _socket_for_reads(self, read_preference, session):
319-
context = super(ReadPrefTester, self)._socket_for_reads(
320-
read_preference, session)
318+
def _socket_for_reads(self, read_preference):
319+
context = super(ReadPrefTester, self)._socket_for_reads(read_preference)
321320
with context as (sock_info, slave_ok):
322321
self.record_a_read(sock_info.address)
323322
yield sock_info, slave_ok

0 commit comments

Comments
 (0)