]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Disallow pool re-opening
authorDenis Laxalde <denis.laxalde@dalibo.com>
Tue, 16 Nov 2021 09:55:26 +0000 (10:55 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 3 Jan 2022 15:41:10 +0000 (16:41 +0100)
There seems to be no use case for re-opening a closed pool, so disable
this now (until we find a real use-case).

docs/news_pool.rst
psycopg_pool/psycopg_pool/base.py
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 62c6a33558ca0a5d96b30285d0d3f381b695a687..08a1b70e0d201e96b7192a004366feef886a45f5 100644 (file)
@@ -15,6 +15,8 @@ psycopg_pool 3.1.0
 
 - Add `ConnectionPool.open()` and `AsyncConnectionPool.open()`
   (:ticket:`#155`).
+- Raise an `~psycopg.OperationalError` when trying to re-open a closed pool
+  (:ticket:`#155`).
 
 psycopg_pool 3.0.2
 ^^^^^^^^^^^^^^^^^^
index 129ffc623c432c9638b3bc4c898cef306ab19d50..8c1b66849081cd5416e613867e28ed382895d7be 100644 (file)
@@ -8,6 +8,7 @@ from random import random
 from typing import Any, Callable, Dict, Generic, Optional
 
 from psycopg.abc import ConnectionType
+from psycopg import errors as e
 
 from ._compat import Counter, Deque
 
@@ -94,6 +95,7 @@ class BasePool(Generic[ConnectionType]):
         # connections to the pool.
         self._growing = False
 
+        self._opened = False
         self._closed = True
 
     def __repr__(self) -> str:
@@ -115,6 +117,12 @@ class BasePool(Generic[ConnectionType]):
         """`!True` if the pool is closed."""
         return self._closed
 
+    def _check_open(self) -> None:
+        if self._closed and self._opened:
+            raise e.OperationalError(
+                "pool has already been opened/closed and cannot be reused"
+            )
+
     def get_stats(self) -> Dict[str, int]:
         """
         Return current stats about the pool usage.
index f92de0bed417d9099b1813c2cb4579d030a2518b..71479d41b656522fd0918fcd0c1acb6fea1ebbb2 100644 (file)
@@ -231,6 +231,8 @@ class ConnectionPool(BasePool[Connection[Any]]):
         if not self._closed:
             return
 
+        self._check_open()
+
         self._sched_runner = threading.Thread(
             target=self._sched.run, name=f"{self.name}-scheduler", daemon=True
         )
@@ -258,6 +260,7 @@ class ConnectionPool(BasePool[Connection[Any]]):
         self.schedule_task(ShrinkPool(self), self.max_idle)
 
         self._closed = False
+        self._opened = True
 
     def close(self, timeout: float = 5.0) -> None:
         """Close the pool and make it unavailable to new clients.
index c954898b1386511508ae028eb44de34e5525958a..46a3bd062475aa8b0d1e7c63f8a983a61448ada4 100644 (file)
@@ -198,6 +198,8 @@ class AsyncConnectionPool(BasePool[AsyncConnection[Any]]):
         if not self._closed:
             return
 
+        self._check_open()
+
         self._sched_runner = create_task(
             self._sched.run(), name=f"{self.name}-scheduler"
         )
@@ -217,6 +219,7 @@ class AsyncConnectionPool(BasePool[AsyncConnection[Any]]):
         self.run_task(Schedule(self, ShrinkPool(self), self.max_idle))
 
         self._closed = False
+        self._opened = True
 
     async def close(self, timeout: float = 5.0) -> None:
         if self._closed:
index 47f90ee5dc39a67e871f4ab7dd8ee52dd532bd8f..ba2812b58d0aab2b2710cb83958aaa6df98292e6 100644 (file)
@@ -8,6 +8,7 @@ from typing import Any, List, Tuple
 import pytest
 
 import psycopg
+from psycopg.errors import OperationalError
 from psycopg.pq import TransactionStatus
 from psycopg._compat import Counter
 
@@ -690,12 +691,9 @@ def test_reopen(dsn):
     p.close()
     assert p._sched_runner is None
     assert not p._workers
-    p.open()
-    assert p._sched_runner is not None
-    assert p._workers
-    with p.connection() as conn:
-        conn.execute("select 1")
-    p.close()
+
+    with pytest.raises(OperationalError, match="cannot be reused"):
+        p.open()
 
 
 @pytest.mark.slow
index fb12ecbf8f125e1c713de43eb7d870f4a3aafbc9..7c2a9ae9ff805867fde94dc1768a1c172aa1fa6c 100644 (file)
@@ -7,6 +7,7 @@ from typing import Any, List, Tuple
 import pytest
 
 import psycopg
+from psycopg.errors import OperationalError
 from psycopg.pq import TransactionStatus
 from psycopg._compat import create_task, Counter
 
@@ -678,11 +679,9 @@ async def test_reopen(dsn):
         await conn.execute("select 1")
     await p.close()
     assert p._sched_runner is None
-    p.open()
-    assert p._sched_runner is not None
-    async with p.connection() as conn:
-        await conn.execute("select 1")
-    await p.close()
+
+    with pytest.raises(OperationalError, match="cannot be reused"):
+        p.open()
 
 
 @pytest.mark.slow