Skip to content

Commit 1a0b180

Browse files
committed
Avoid interpreter teardown exceptions.
1 parent ac0ccc6 commit 1a0b180

File tree

1 file changed

+11
-29
lines changed

1 file changed

+11
-29
lines changed

pymongo/pool.py

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -63,33 +63,37 @@ def _closed(sock):
6363
class SocketInfo(object):
6464
"""Store a socket with some metadata
6565
"""
66-
def __init__(self, sock, pool):
66+
def __init__(self, sock, poolref):
6767
self.sock = sock
6868

6969
# We can't strongly reference the Pool, because the Pool
7070
# references this SocketInfo as long as it's in pool
71-
self.poolref = weakref.ref(pool)
71+
self.poolref = poolref
7272

7373
self.authset = set()
7474
self.closed = False
7575
self.last_checkout = time.time()
76-
self.pool_id = pool.pool_id
76+
self.pool_id = poolref().pool_id
7777

7878
def close(self):
79-
self.sock.close()
8079
self.closed = True
80+
# Avoid exceptions on interpreter shutdown.
81+
try:
82+
self.sock.close()
83+
except:
84+
pass
8185

8286
def __del__(self):
8387
if not self.closed:
8488
# This socket was given out, but not explicitly returned. Perhaps
8589
# the socket was assigned to a thread local for a request, but the
8690
# request wasn't ended before the thread died. Reclaim the socket
8791
# for the pool.
88-
pool = self.poolref and self.poolref()
92+
pool = self.poolref()
8993
if pool:
9094
# Return a copy of self rather than self -- the Python docs
9195
# discourage postponing deletion by adding a reference to self.
92-
copy = SocketInfo(self.sock, pool)
96+
copy = SocketInfo(self.sock, self.poolref)
9397
copy.authset = self.authset
9498
pool.return_socket(copy)
9599
else:
@@ -220,7 +224,7 @@ def connect(self, pair):
220224
"not be configured with SSL support.")
221225

222226
sock.settimeout(self.net_timeout)
223-
return SocketInfo(sock, self)
227+
return SocketInfo(sock, weakref.ref(self))
224228

225229
def get_socket(self, pair=None):
226230
"""Get a socket from the pool.
@@ -384,18 +388,6 @@ def __init__(self, *args, **kwargs):
384388
self.local = _Local()
385389
super(Pool, self).__init__(*args, **kwargs)
386390

387-
def __del__(self):
388-
# If we're being deleted on a thread that started a request, then the
389-
# request socket might still be in a thread-local; get it and close it.
390-
# The 'hasattr' checks avoid TypeError during interpreter shutdown.
391-
request_sock = self._get_request_state()
392-
if hasattr(request_sock, 'close'):
393-
request_sock.close()
394-
395-
for sock_info in self.sockets:
396-
if hasattr(sock_info, 'close'):
397-
sock_info.close()
398-
399391
def _set_request_state(self, sock_info):
400392
self.local.sock_info = sock_info
401393

@@ -419,16 +411,6 @@ def __init__(self, *args, **kwargs):
419411
self._refs = {}
420412
super(GreenletPool, self).__init__(*args, **kwargs)
421413

422-
def __del__(self):
423-
# The 'hasattr' checks avoid TypeError during interpreter shutdown.
424-
for sock_info in self._gr_id_to_sock.values():
425-
if hasattr(sock_info, 'close'):
426-
sock_info.close()
427-
428-
for sock_info in self.sockets:
429-
if hasattr(sock_info, 'close'):
430-
sock_info.close()
431-
432414
# Overrides
433415
def _set_request_state(self, sock_info):
434416
current = greenlet.getcurrent()

0 commit comments

Comments
 (0)