]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix(pool): allow growing again after failing a growing connection attempt
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Tue, 6 Sep 2022 16:53:40 +0000 (17:53 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Tue, 6 Sep 2022 16:53:40 +0000 (17:53 +0100)
Fix #370

docs/news_pool.rst
psycopg_pool/psycopg_pool/pool.py
psycopg_pool/psycopg_pool/pool_async.py
tests/pool/test_pool.py
tests/pool/test_pool_async.py

index f4aef6abefbb665a1c5c9d13f07cb0ea6a6eba1d..b2ecf0bbc7acc3822d5f4e85c6c76b19b1f0ab4e 100644 (file)
@@ -7,6 +7,16 @@
 ``psycopg_pool`` release notes
 ==============================
 
+Future releases
+---------------
+
+psycopg_pool 3.1.2 (unreleased)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Fix possible failure to reconnect after losing connection from the server
+  (:ticket:`#370`).
+
+
 Current release
 ---------------
 
index 9eb052e4cd0dbfbfd4f420987017bce3e0163dd7..0f3cf535acdff74d2acc7624091ff8b445943825 100644 (file)
@@ -527,6 +527,9 @@ class ConnectionPool(BasePool[Connection[Any]]):
                 )
                 with self._lock:
                     self._nconns -= 1
+                    # If we have given up with a growing attempt, allow a new one.
+                    if growing and self._growing:
+                        self._growing = False
                 self.reconnect_failed()
             else:
                 attempt.update_delay(now)
index 864a50019cf32ae8c383a8e9a21deba1f4f97b0f..e54d7b19aa9a4cbc4c2fb898df85cc430ee0aa85 100644 (file)
@@ -428,6 +428,9 @@ class AsyncConnectionPool(BasePool[AsyncConnection[Any]]):
                 )
                 async with self._lock:
                     self._nconns -= 1
+                    # If we have given up with a growing attempt, allow a new one.
+                    if growing and self._growing:
+                        self._growing = False
                 self.reconnect_failed()
             else:
                 attempt.update_delay(now)
index 0089054116e72325883b7de5c6bc98f1437e3b18..51d800a82e34a0125cf3ccca8a7bc27be39e7173 100644 (file)
@@ -921,6 +921,33 @@ def test_reconnect_failure(proxy):
         assert t1 - t0 < 0.2
 
 
+@pytest.mark.slow
+def test_reconnect_retry(proxy):
+    proxy.stop()
+
+    ev = Event()
+
+    def failed(pool):
+        ev.set()
+
+    with pool.ConnectionPool(
+        proxy.client_dsn, reconnect_timeout=1.0, reconnect_failed=failed
+    ) as p:
+        assert ev.wait(timeout=2)
+
+        with pytest.raises(pool.PoolTimeout):
+            with p.connection(timeout=0.5) as conn:
+                pass
+
+        ev.clear()
+        assert ev.wait(timeout=2)
+
+        proxy.start()
+
+        with p.connection(timeout=2) as conn:
+            conn.execute("select 1")
+
+
 @pytest.mark.slow
 def test_uniform_use(dsn):
     with pool.ConnectionPool(dsn, min_size=4) as p:
index b67a575e1276b30e412ae9225b3051e4af21f23a..6c923e63896096d208e6c841f299ec1ff0ce9684 100644 (file)
@@ -873,6 +873,33 @@ async def test_reconnect_failure(proxy):
         assert t1 - t0 < 0.2
 
 
+@pytest.mark.slow
+async def test_reconnect_retry(proxy):
+    proxy.stop()
+
+    ev = asyncio.Event()
+
+    def failed(pool):
+        ev.set()
+
+    async with pool.AsyncConnectionPool(
+        proxy.client_dsn, reconnect_timeout=1.0, reconnect_failed=failed
+    ) as p:
+        await asyncio.wait_for(ev.wait(), 2.0)
+
+        with pytest.raises(pool.PoolTimeout):
+            async with p.connection(timeout=0.5) as conn:
+                pass
+
+        ev.clear()
+        await asyncio.wait_for(ev.wait(), 2.0)
+
+        proxy.start()
+
+        async with p.connection(timeout=2) as conn:
+            await conn.execute("select 1")
+
+
 @pytest.mark.slow
 async def test_uniform_use(dsn):
     async with pool.AsyncConnectionPool(dsn, min_size=4) as p: