Make it explicit in the documentation and in the default value for the 'timeout'
parameter that `timeout` can be a float. Because Python timing is not
very accurate, warn about the precision.
:paramref:`_pool.Pool.reset_on_return`
- :param pool_timeout=30: number of seconds to wait before giving
+ :param pool_timeout=30.0: number of seconds to wait before giving
up on getting a connection from the pool. This is only used
- with :class:`~sqlalchemy.pool.QueuePool`.
+ with :class:`~sqlalchemy.pool.QueuePool`. This can be a float but is
+ subject to the limitations of Python time functions which may not be
+ reliable in the tens of milliseconds.
:param pool_use_lifo=False: use LIFO (last-in-first-out) when retrieving
connections from :class:`.QueuePool` instead of FIFO
creator,
pool_size=5,
max_overflow=10,
- timeout=30,
+ timeout=30.0,
use_lifo=False,
**kw
):
connections. Defaults to 10.
:param timeout: The number of seconds to wait before giving up
- on returning a connection. Defaults to 30.
+ on returning a connection. Defaults to 30.0. This can be a float
+ but is subject to the limitations of Python time functions which
+ may not be reliable in the tens of milliseconds.
:param use_lifo: use LIFO (last-in-first-out) when retrieving
connections instead of FIFO (first-in-first-out). Using LIFO, a
else:
raise exc.TimeoutError(
"QueuePool limit of size %d overflow %d reached, "
- "connection timed out, timeout %d"
+ "connection timed out, timeout %0.2f"
% (self.size(), self.overflow(), self._timeout),
code="3o7r",
)
import time
import weakref
+import pytest
+
import sqlalchemy as tsa
from sqlalchemy import event
from sqlalchemy import pool
assert_raises(tsa.exc.TimeoutError, p.connect)
assert int(time.time() - now) == 2
+ @testing.requires.timing_intensive
+ def test_timeout_subsecond_precision(self):
+ p = self._queuepool_fixture(pool_size=1, max_overflow=0, timeout=0.5)
+ c1 = p.connect() # noqa
+ with pytest.raises(tsa.exc.TimeoutError, match=r".* timeout 0.50 .*"):
+ now = time.time()
+ c2 = p.connect() # noqa
+ # Python timing is not very accurate, the time diff should be very
+ # close to 0.5s but we give 200ms of slack.
+ assert 0.3 <= time.time() - now <= 0.7, "Pool timeout not respected"
+
@testing.requires.threading_with_mock
@testing.requires.timing_intensive
def test_timeout_race(self):