Issue #2772 resolved

overflow counter not handled on particular exception case

Michael Bayer
repo owner created an issue

need to write mock tests for this, the idea is:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from time import sleep
from traceback import print_exc
from sqlalchemy import create_engine
import logging

logging.basicConfig()
logger = logging.getLogger('sqlalchemy.pool')
logger.setLevel(logging.DEBUG)

connection_string = "mysql://<hidden connection string>"

engine = create_engine(connection_string, pool_recycle=1)

print("open and close a connection so that it is returned to the pool")

conn = engine.pool.connect()
assert engine.pool.checkedout() == 1
conn.close()
assert engine.pool.checkedout() == 0

sleep(1)
raw_input("""
because of pool_recycle, the connection in pool should have expired by now

now - break DNS so that connect() will fail
you can easily do this by adding the hostname in
/etc/hosts and pointing it to 127.0.0.1

press enter when ready
""")

try:
    conn = engine.pool.connect()
except:
    print_exc()
    print
    if engine.pool.checkedout() > 0:
        print("BUG reproduced: checkedout() should have returned 0")
    else:
        raise Exception("failed to reproduce")
else:
    raise Exception("connection succeeded - did you break DNS?")

suggested patch in 0.8 is:

-- SQLAlchemy-0.8.1/SQLAlchemy-0.8.1/lib/sqlalchemy/pool.py    2013-06-21 15:44:01.000000000 -0700
+++ SQLAlchemy-0.8.1.fbar.fix.leak/SQLAlchemy-0.8.1/lib/sqlalchemy/pool.py      2013-06-21 17:47:12.000000000 -0700
@@ -423,7 +423,11 @@
         self._echo = _echo = pool._should_log_debug()
         try:
             rec = self._connection_record = pool._do_get()
-            conn = self.connection = self._connection_record.get_connection()
+            try:
+                conn = self.connection = self._connection_record.get_connection()
+            except:
+                _finalize_fairy(None, rec, pool, None, _echo)
+                raise
             rec.fairy = weakref.ref(
                             self,
                             lambda ref: _finalize_fairy and \

Comments (2)

  1. Log in to comment