Skip to content

Commit b04e334

Browse files
authored
PYTHON-2328 Reset the connection pool in Topology.on_change (#470)
PYTHON-2304 Ensure _RttMonitor closes socket on when the client is closed
1 parent c16b5b9 commit b04e334

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

pymongo/monitor.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -177,20 +177,20 @@ def _run(self):
177177
# discover that we've been cancelled.
178178
self._executor.skip_sleep()
179179
return
180-
self._topology.on_change(self._server_description)
180+
181+
# Update the Topology and clear the server pool on error.
182+
self._topology.on_change(self._server_description,
183+
reset_pool=self._server_description.error)
181184

182185
if (self._server_description.is_server_type_known and
183186
self._server_description.topology_version):
184187
self._start_rtt_monitor()
185188
# Immediately check for the next streaming response.
186189
self._executor.skip_sleep()
187190

188-
if self._server_description.error:
189-
# Reset the server pool only after marking the server Unknown.
190-
self._topology.reset_pool(self._server_description.address)
191-
if prev_sd.is_server_type_known:
192-
# Immediately retry on network errors.
193-
self._executor.skip_sleep()
191+
if self._server_description.error and prev_sd.is_server_type_known:
192+
# Immediately retry on network errors.
193+
self._executor.skip_sleep()
194194
except ReferenceError:
195195
# Topology was garbage-collected.
196196
self.close()
@@ -377,6 +377,8 @@ def _run(self):
377377
def _ping(self):
378378
"""Run an "isMaster" command and return the RTT."""
379379
with self._pool.get_socket({}) as sock_info:
380+
if self._executor._stopped:
381+
raise Exception('_RttMonitor closed')
380382
start = _time()
381383
sock_info.ismaster()
382384
return _time() - start

pymongo/topology.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ def select_server_by_address(self, address,
265265
server_selection_timeout,
266266
address)
267267

268-
def _process_change(self, server_description):
268+
def _process_change(self, server_description, reset_pool=False):
269269
"""Process a new ServerDescription on an opened topology.
270270
271271
Hold the lock when calling this.
@@ -303,10 +303,16 @@ def _process_change(self, server_description):
303303
SRV_POLLING_TOPOLOGIES):
304304
self._srv_monitor.close()
305305

306+
# Clear the pool from a failed heartbeat.
307+
if reset_pool:
308+
server = self._servers.get(server_description.address)
309+
if server:
310+
server.pool.reset()
311+
306312
# Wake waiters in select_servers().
307313
self._condition.notify_all()
308314

309-
def on_change(self, server_description):
315+
def on_change(self, server_description, reset_pool=False):
310316
"""Process a new ServerDescription after an ismaster call completes."""
311317
# We do no I/O holding the lock.
312318
with self._lock:
@@ -320,7 +326,7 @@ def on_change(self, server_description):
320326
# that didn't include this server.
321327
if (self._opened and
322328
self._description.has_server(server_description.address)):
323-
self._process_change(server_description)
329+
self._process_change(server_description, reset_pool)
324330

325331
def _process_srv_update(self, seedlist):
326332
"""Process a new seedlist on an opened topology.
@@ -414,20 +420,14 @@ def request_check_all(self, wait_time=5):
414420
self._request_check_all()
415421
self._condition.wait(wait_time)
416422

417-
def reset_pool(self, address):
418-
with self._lock:
419-
server = self._servers.get(address)
420-
if server:
421-
server.pool.reset()
422-
423423
def handle_getlasterror(self, address, error_msg):
424424
"""Clear our pool for a server, mark it Unknown, and check it soon."""
425425
error = NotMasterError(error_msg, {'code': 10107, 'errmsg': error_msg})
426426
with self._lock:
427427
server = self._servers.get(address)
428428
if server:
429-
self._process_change(ServerDescription(address, error=error))
430-
server.pool.reset()
429+
self._process_change(
430+
ServerDescription(address, error=error), True)
431431
server.request_check()
432432

433433
def update_pool(self, all_credentials):

0 commit comments

Comments
 (0)