From: Mike Bayer Date: Mon, 14 Sep 2020 14:14:48 +0000 (-0400) Subject: Pass all pool parameters in recreate() X-Git-Tag: rel_1_4_0b1~97^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3d803a8ed3e07332dff872180680bed6175dd483;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Pass all pool parameters in recreate() The following pool parameters were not being propagated to the new pool created when :meth:`_engine.Engine.dispose` were called: ``pre_ping``, ``use_lifo``. Additionally the ``recycle`` and ``reset_on_return`` parameters were not propagated for the :class:`_engine.AssertionPool` class. These issues have been fixed. Fixes: #5582 Change-Id: Ifdb703aa7e849652242b9ff8071c854cd1d77e71 --- diff --git a/doc/build/changelog/unreleased_13/5582.rst b/doc/build/changelog/unreleased_13/5582.rst new file mode 100644 index 0000000000..dca8855d61 --- /dev/null +++ b/doc/build/changelog/unreleased_13/5582.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, pool + :tickets: 5582 + + The following pool parameters were not being propagated to the new pool + created when :meth:`_engine.Engine.dispose` were called: ``pre_ping``, + ``use_lifo``. Additionally the ``recycle`` and ``reset_on_return`` + parameters were not propagated for the :class:`_engine.AssertionPool` + class. These issues have been fixed. diff --git a/lib/sqlalchemy/pool/impl.py b/lib/sqlalchemy/pool/impl.py index e1a9f00db1..a6c0cf1041 100644 --- a/lib/sqlalchemy/pool/impl.py +++ b/lib/sqlalchemy/pool/impl.py @@ -168,6 +168,8 @@ class QueuePool(Pool): self._creator, pool_size=self._pool.maxsize, max_overflow=self._max_overflow, + pre_ping=self._pre_ping, + use_lifo=self._pool.use_lifo, timeout=self._timeout, recycle=self._recycle, echo=self.echo, @@ -252,6 +254,7 @@ class NullPool(Pool): echo=self.echo, logging_name=self._orig_logging_name, reset_on_return=self._reset_on_return, + pre_ping=self._pre_ping, _dispatch=self.dispatch, dialect=self._dialect, ) @@ -305,6 +308,7 @@ class SingletonThreadPool(Pool): pool_size=self.size, recycle=self._recycle, echo=self.echo, + pre_ping=self._pre_ping, logging_name=self._orig_logging_name, reset_on_return=self._reset_on_return, _dispatch=self.dispatch, @@ -406,6 +410,7 @@ class StaticPool(Pool): creator=self._creator, recycle=self._recycle, reset_on_return=self._reset_on_return, + pre_ping=self._pre_ping, echo=self.echo, logging_name=self._orig_logging_name, _dispatch=self.dispatch, @@ -459,6 +464,9 @@ class AssertionPool(Pool): return self.__class__( self._creator, echo=self.echo, + pre_ping=self._pre_ping, + recycle=self._recycle, + reset_on_return=self._reset_on_return, logging_name=self._orig_logging_name, _dispatch=self.dispatch, dialect=self._dialect, diff --git a/lib/sqlalchemy/util/queue.py b/lib/sqlalchemy/util/queue.py index 58a88e4ede..9447abeded 100644 --- a/lib/sqlalchemy/util/queue.py +++ b/lib/sqlalchemy/util/queue.py @@ -209,6 +209,7 @@ class AsyncAdaptedQueue: self._queue = asyncio.LifoQueue(maxsize=maxsize) else: self._queue = asyncio.Queue(maxsize=maxsize) + self.use_lifo = use_lifo self.maxsize = maxsize self.empty = self._queue.empty self.full = self._queue.full diff --git a/test/engine/test_pool.py b/test/engine/test_pool.py index 6f5093b06a..fbe3942386 100644 --- a/test/engine/test_pool.py +++ b/test/engine/test_pool.py @@ -9,6 +9,7 @@ from sqlalchemy import event from sqlalchemy import pool from sqlalchemy import select from sqlalchemy import testing +from sqlalchemy.engine import default from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_context_ok from sqlalchemy.testing import assert_raises_message @@ -17,6 +18,7 @@ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ from sqlalchemy.testing import is_not from sqlalchemy.testing import is_true +from sqlalchemy.testing import mock from sqlalchemy.testing.engines import testing_engine from sqlalchemy.testing.mock import ANY from sqlalchemy.testing.mock import call @@ -25,7 +27,6 @@ from sqlalchemy.testing.mock import patch from sqlalchemy.testing.util import gc_collect from sqlalchemy.testing.util import lazy_gc - join_timeout = 10 @@ -220,6 +221,60 @@ class PoolTest(PoolTestBase): eq_(c2.mock_calls, []) + @testing.combinations( + ( + pool.QueuePool, + dict(pool_size=8, max_overflow=10, timeout=25, use_lifo=True), + ), + (pool.QueuePool, {}), + (pool.NullPool, {}), + (pool.SingletonThreadPool, {}), + (pool.StaticPool, {}), + (pool.AssertionPool, {}), + ) + def test_recreate_state(self, pool_cls, pool_args): + creator = object() + pool_args["pre_ping"] = True + pool_args["reset_on_return"] = "commit" + pool_args["recycle"] = 35 + pool_args["logging_name"] = "somepool" + pool_args["dialect"] = default.DefaultDialect() + pool_args["echo"] = "debug" + + p1 = pool_cls(creator=creator, **pool_args) + + cls_keys = dir(pool_cls) + + d1 = dict(p1.__dict__) + + p2 = p1.recreate() + + d2 = dict(p2.__dict__) + + for k in cls_keys: + d1.pop(k, None) + d2.pop(k, None) + + for k in ( + "_threadconns", + "_invoke_creator", + "_pool", + "_overflow_lock", + "_fairy", + "_conn", + "logger", + ): + if k in d2: + d2[k] = mock.ANY + + eq_(d1, d2) + + eq_(p1.echo, p2.echo) + is_(p1._dialect, p2._dialect) + + if "use_lifo" in pool_args: + eq_(p1._pool.use_lifo, p2._pool.use_lifo) + class PoolDialectTest(PoolTestBase): def _dialect(self):