]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
test(pool): add test to show deadlock on logging
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 19 Feb 2022 14:39:37 +0000 (15:39 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 19 Feb 2022 15:54:02 +0000 (16:54 +0100)
This deadlock seems reproducible at least on Python 3.8 and 3.10 on
Linux. It is caused by the logging statement in
``MaintenanceTask.__init__``: even just a ``print()`` there causes the lock.

See https://github.com/psycopg/psycopg/issues/230 for more details.

tests/pool/test_pool.py
tests/pool/test_pool_async.py

index b3b67392e97eabb158544d3f34db038d6d8e1414..84954fe2fef28833f54948b11f7be0dfc9604f7f 100644 (file)
@@ -1151,6 +1151,25 @@ def test_spike(dsn, monkeypatch):
         assert len(p._pool) < 7
 
 
+def test_debug_deadlock(dsn):
+    # https://github.com/psycopg/psycopg/issues/230
+    logger = logging.getLogger("psycopg")
+    handler = logging.StreamHandler()
+    old_level = logger.level
+    logger.setLevel(logging.DEBUG)
+    handler.setLevel(logging.DEBUG)
+    logger.addHandler(handler)
+    try:
+        with pool.ConnectionPool(dsn, min_size=4, open=True) as p:
+            try:
+                p.wait(timeout=2)
+            finally:
+                print(p.get_stats())
+    finally:
+        logger.removeHandler(handler)
+        logger.setLevel(old_level)
+
+
 def delay_connection(monkeypatch, sec):
     """
     Return a _connect_gen function delayed by the amount of seconds
index 436e5dcb221ad7314ba91e5e6f6896595b905f3d..3a26a98f032e9a354fdda2be595bfb71f4ef4091 100644 (file)
@@ -1087,6 +1087,22 @@ async def test_spike(dsn, monkeypatch):
         assert len(p._pool) < 7
 
 
+async def test_debug_deadlock(dsn):
+    # https://github.com/psycopg/psycopg/issues/230
+    logger = logging.getLogger("psycopg")
+    handler = logging.StreamHandler()
+    old_level = logger.level
+    logger.setLevel(logging.DEBUG)
+    handler.setLevel(logging.DEBUG)
+    logger.addHandler(handler)
+    try:
+        async with pool.AsyncConnectionPool(dsn, min_size=4, open=True) as p:
+            await p.wait(timeout=2)
+    finally:
+        logger.removeHandler(handler)
+        logger.setLevel(old_level)
+
+
 def delay_connection(monkeypatch, sec):
     """
     Return a _connect_gen function delayed by the amount of seconds