From: Daniele Varrazzo Date: Fri, 26 Jan 2024 11:49:23 +0000 (+0000) Subject: refactor: rename wait functions 'timeout' parameter to 'interval' X-Git-Tag: 3.2.0~61^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F766%2Fhead;p=thirdparty%2Fpsycopg.git refactor: rename wait functions 'timeout' parameter to 'interval' --- diff --git a/psycopg/psycopg/abc.py b/psycopg/psycopg/abc.py index ad4a96646..480fc064c 100644 --- a/psycopg/psycopg/abc.py +++ b/psycopg/psycopg/abc.py @@ -56,7 +56,7 @@ class WaitFunc(Protocol): """ def __call__( - self, gen: PQGen[RV], fileno: int, timeout: Optional[float] = None + self, gen: PQGen[RV], fileno: int, interval: Optional[float] = None ) -> RV: ... diff --git a/psycopg/psycopg/connection.py b/psycopg/psycopg/connection.py index 977b6a7ad..65c1b1dcd 100644 --- a/psycopg/psycopg/connection.py +++ b/psycopg/psycopg/connection.py @@ -101,7 +101,7 @@ class Connection(BaseConnection[Row]): try: conninfo = make_conninfo("", **attempt) gen = cls._connect_gen(conninfo, timeout=timeout) - rv = waiting.wait_conn(gen, timeout=_WAIT_INTERVAL) + rv = waiting.wait_conn(gen, interval=_WAIT_INTERVAL) except e._NO_TRACEBACK as ex: if len(attempts) > 1: logger.debug( @@ -298,10 +298,10 @@ class Connection(BaseConnection[Row]): # into shorter interval. if timeout is not None: deadline = monotonic() + timeout - timeout = min(timeout, _WAIT_INTERVAL) + interval = min(timeout, _WAIT_INTERVAL) else: deadline = None - timeout = _WAIT_INTERVAL + interval = _WAIT_INTERVAL nreceived = 0 @@ -310,7 +310,7 @@ class Connection(BaseConnection[Row]): # notification is received to makes sure that they are consistent. try: with self.lock: - ns = self.wait(notifies(self.pgconn), timeout=timeout) + ns = self.wait(notifies(self.pgconn), interval=interval) if ns: enc = pgconn_encoding(self.pgconn) except e._NO_TRACEBACK as ex: @@ -329,8 +329,8 @@ class Connection(BaseConnection[Row]): # Check the deadline after the loop to ensure that timeout=0 # polls at least once. if deadline: - timeout = min(_WAIT_INTERVAL, deadline - monotonic()) - if timeout < 0.0: + interval = min(_WAIT_INTERVAL, deadline - monotonic()) + if interval < 0.0: break @contextmanager @@ -353,7 +353,7 @@ class Connection(BaseConnection[Row]): assert pipeline is self._pipeline self._pipeline = None - def wait(self, gen: PQGen[RV], timeout: Optional[float] = _WAIT_INTERVAL) -> RV: + def wait(self, gen: PQGen[RV], interval: Optional[float] = _WAIT_INTERVAL) -> RV: """ Consume a generator operating on the connection. @@ -361,14 +361,14 @@ class Connection(BaseConnection[Row]): fd (i.e. not on connect and reset). """ try: - return waiting.wait(gen, self.pgconn.socket, timeout=timeout) + return waiting.wait(gen, self.pgconn.socket, interval=interval) except _INTERRUPTED: if self.pgconn.transaction_status == ACTIVE: # On Ctrl-C, try to cancel the query in the server, otherwise # the connection will remain stuck in ACTIVE state. self._try_cancel(self.pgconn) try: - waiting.wait(gen, self.pgconn.socket, timeout=timeout) + waiting.wait(gen, self.pgconn.socket, interval=interval) except e.QueryCanceled: pass # as expected raise diff --git a/psycopg/psycopg/connection_async.py b/psycopg/psycopg/connection_async.py index 0e1a7799b..4e67c5ef8 100644 --- a/psycopg/psycopg/connection_async.py +++ b/psycopg/psycopg/connection_async.py @@ -116,7 +116,7 @@ class AsyncConnection(BaseConnection[Row]): try: conninfo = make_conninfo("", **attempt) gen = cls._connect_gen(conninfo, timeout=timeout) - rv = await waiting.wait_conn_async(gen, timeout=_WAIT_INTERVAL) + rv = await waiting.wait_conn_async(gen, interval=_WAIT_INTERVAL) except e._NO_TRACEBACK as ex: if len(attempts) > 1: logger.debug( @@ -314,10 +314,10 @@ class AsyncConnection(BaseConnection[Row]): # into shorter interval. if timeout is not None: deadline = monotonic() + timeout - timeout = min(timeout, _WAIT_INTERVAL) + interval = min(timeout, _WAIT_INTERVAL) else: deadline = None - timeout = _WAIT_INTERVAL + interval = _WAIT_INTERVAL nreceived = 0 @@ -326,7 +326,7 @@ class AsyncConnection(BaseConnection[Row]): # notification is received to makes sure that they are consistent. try: async with self.lock: - ns = await self.wait(notifies(self.pgconn), timeout=timeout) + ns = await self.wait(notifies(self.pgconn), interval=interval) if ns: enc = pgconn_encoding(self.pgconn) except e._NO_TRACEBACK as ex: @@ -345,8 +345,8 @@ class AsyncConnection(BaseConnection[Row]): # Check the deadline after the loop to ensure that timeout=0 # polls at least once. if deadline: - timeout = min(_WAIT_INTERVAL, deadline - monotonic()) - if timeout < 0.0: + interval = min(_WAIT_INTERVAL, deadline - monotonic()) + if interval < 0.0: break @asynccontextmanager @@ -370,7 +370,7 @@ class AsyncConnection(BaseConnection[Row]): self._pipeline = None async def wait( - self, gen: PQGen[RV], timeout: Optional[float] = _WAIT_INTERVAL + self, gen: PQGen[RV], interval: Optional[float] = _WAIT_INTERVAL ) -> RV: """ Consume a generator operating on the connection. @@ -379,14 +379,14 @@ class AsyncConnection(BaseConnection[Row]): fd (i.e. not on connect and reset). """ try: - return await waiting.wait_async(gen, self.pgconn.socket, timeout=timeout) + return await waiting.wait_async(gen, self.pgconn.socket, interval=interval) except _INTERRUPTED: if self.pgconn.transaction_status == ACTIVE: # On Ctrl-C, try to cancel the query in the server, otherwise # the connection will remain stuck in ACTIVE state. self._try_cancel(self.pgconn) try: - await waiting.wait_async(gen, self.pgconn.socket, timeout=timeout) + await waiting.wait_async(gen, self.pgconn.socket, interval=interval) except e.QueryCanceled: pass # as expected raise diff --git a/psycopg/psycopg/waiting.py b/psycopg/psycopg/waiting.py index 1d938830e..1247a8dd3 100644 --- a/psycopg/psycopg/waiting.py +++ b/psycopg/psycopg/waiting.py @@ -34,16 +34,15 @@ READY_RW = Ready.RW logger = logging.getLogger(__name__) -def wait_selector(gen: PQGen[RV], fileno: int, timeout: Optional[float] = None) -> RV: +def wait_selector(gen: PQGen[RV], fileno: int, interval: Optional[float] = None) -> RV: """ Wait for a generator using the best strategy available. :param gen: a generator performing database operations and yielding `Ready` values when it would block. :param fileno: the file descriptor to wait on. - :param timeout: timeout (in seconds) to check for other interrupt, e.g. - to allow Ctrl-C. - :type timeout: float + :param interval: interval (in seconds) to check for other interrupt, e.g. + to allow Ctrl-C. If zero or None, wait indefinitely. :return: whatever `!gen` returns on completion. Consume `!gen`, scheduling `fileno` for completion when it is reported to @@ -54,7 +53,7 @@ def wait_selector(gen: PQGen[RV], fileno: int, timeout: Optional[float] = None) with DefaultSelector() as sel: sel.register(fileno, s) while True: - rlist = sel.select(timeout=timeout) + rlist = sel.select(timeout=interval) if not rlist: gen.send(READY_NONE) continue @@ -69,15 +68,14 @@ def wait_selector(gen: PQGen[RV], fileno: int, timeout: Optional[float] = None) return rv -def wait_conn(gen: PQGenConn[RV], timeout: Optional[float] = None) -> RV: +def wait_conn(gen: PQGenConn[RV], interval: Optional[float] = None) -> RV: """ Wait for a connection generator using the best strategy available. :param gen: a generator performing database operations and yielding (fd, `Ready`) pairs when it would block. - :param timeout: timeout (in seconds) to check for other interrupt, e.g. + :param interval: interval (in seconds) to check for other interrupt, e.g. to allow Ctrl-C. If zero or None, wait indefinitely. - :type timeout: float :return: whatever `!gen` returns on completion. Behave like in `wait()`, but take the fileno to wait from the generator @@ -85,12 +83,12 @@ def wait_conn(gen: PQGenConn[RV], timeout: Optional[float] = None) -> RV: """ try: fileno, s = next(gen) - if not timeout: - timeout = None + if not interval: + interval = None with DefaultSelector() as sel: sel.register(fileno, s) while True: - rlist = sel.select(timeout=timeout) + rlist = sel.select(timeout=interval) if not rlist: gen.send(READY_NONE) continue @@ -106,7 +104,7 @@ def wait_conn(gen: PQGenConn[RV], timeout: Optional[float] = None) -> RV: async def wait_async( - gen: PQGen[RV], fileno: int, timeout: Optional[float] = None + gen: PQGen[RV], fileno: int, interval: Optional[float] = None ) -> RV: """ Coroutine waiting for a generator to complete. @@ -114,8 +112,8 @@ async def wait_async( :param gen: a generator performing database operations and yielding `Ready` values when it would block. :param fileno: the file descriptor to wait on. - :param timeout: timeout (in seconds) to check for other interrupt, e.g. - to allow Ctrl-C. If zero, wait indefinitely. + :param interval: interval (in seconds) to check for other interrupt, e.g. + to allow Ctrl-C. If None, wait indefinitely. :return: whatever `!gen` returns on completion. Behave like in `wait()`, but exposing an `asyncio` interface. @@ -146,9 +144,9 @@ async def wait_async( if writer: loop.add_writer(fileno, wakeup, READY_W) try: - if timeout is not None: + if interval is not None: try: - await wait_for(ev.wait(), timeout) + await wait_for(ev.wait(), interval) except TimeoutError: pass else: @@ -168,13 +166,13 @@ async def wait_async( return rv -async def wait_conn_async(gen: PQGenConn[RV], timeout: Optional[float] = None) -> RV: +async def wait_conn_async(gen: PQGenConn[RV], interval: Optional[float] = None) -> RV: """ Coroutine waiting for a connection generator to complete. :param gen: a generator performing database operations and yielding (fd, `Ready`) pairs when it would block. - :param timeout: timeout (in seconds) to check for other interrupt, e.g. + :param interval: interval (in seconds) to check for other interrupt, e.g. to allow Ctrl-C. If zero or None, wait indefinitely. :return: whatever `!gen` returns on completion. @@ -207,9 +205,9 @@ async def wait_conn_async(gen: PQGenConn[RV], timeout: Optional[float] = None) - if writer: loop.add_writer(fileno, wakeup, READY_W) try: - if timeout: + if interval: try: - await wait_for(ev.wait(), timeout) + await wait_for(ev.wait(), interval) except TimeoutError: pass else: @@ -229,7 +227,7 @@ async def wait_conn_async(gen: PQGenConn[RV], timeout: Optional[float] = None) - # Specialised implementation of wait functions. -def wait_select(gen: PQGen[RV], fileno: int, timeout: Optional[float] = None) -> RV: +def wait_select(gen: PQGen[RV], fileno: int, interval: Optional[float] = None) -> RV: """ Wait for a generator using select where supported. @@ -245,7 +243,7 @@ def wait_select(gen: PQGen[RV], fileno: int, timeout: Optional[float] = None) -> fnlist if s & WAIT_R else empty, fnlist if s & WAIT_W else empty, fnlist, - timeout, + interval, ) ready = 0 if rl: @@ -274,7 +272,7 @@ else: _epoll_evmasks = {} -def wait_epoll(gen: PQGen[RV], fileno: int, timeout: Optional[float] = None) -> RV: +def wait_epoll(gen: PQGen[RV], fileno: int, interval: Optional[float] = None) -> RV: """ Wait for a generator using epoll where supported. @@ -293,14 +291,14 @@ def wait_epoll(gen: PQGen[RV], fileno: int, timeout: Optional[float] = None) -> try: s = next(gen) - if timeout is None or timeout < 0: - timeout = 0.0 + if interval is None or interval < 0: + interval = 0.0 with select.epoll() as epoll: evmask = _epoll_evmasks[s] epoll.register(fileno, evmask) while True: - fileevs = epoll.poll(timeout) + fileevs = epoll.poll(interval) if not fileevs: gen.send(READY_NONE) continue @@ -329,7 +327,7 @@ else: _poll_evmasks = {} -def wait_poll(gen: PQGen[RV], fileno: int, timeout: Optional[float] = None) -> RV: +def wait_poll(gen: PQGen[RV], fileno: int, interval: Optional[float] = None) -> RV: """ Wait for a generator using poll where supported. @@ -338,16 +336,16 @@ def wait_poll(gen: PQGen[RV], fileno: int, timeout: Optional[float] = None) -> R try: s = next(gen) - if timeout is None or timeout < 0: - timeout = 0 + if interval is None or interval < 0: + interval = 0 else: - timeout = int(timeout * 1000.0) + interval = int(interval * 1000.0) poll = select.poll() evmask = _poll_evmasks[s] poll.register(fileno, evmask) while True: - fileevs = poll.poll(timeout) + fileevs = poll.poll(interval) if not fileevs: gen.send(READY_NONE) continue diff --git a/psycopg_c/psycopg_c/_psycopg.pyi b/psycopg_c/psycopg_c/_psycopg.pyi index 10d230bfb..ec976eb5c 100644 --- a/psycopg_c/psycopg_c/_psycopg.pyi +++ b/psycopg_c/psycopg_c/_psycopg.pyi @@ -60,7 +60,7 @@ def pipeline_communicate( pgconn: PGconn, commands: Deque[abc.PipelineCommand] ) -> abc.PQGen[List[List[PGresult]]]: ... def wait_c( - gen: abc.PQGen[abc.RV], fileno: int, timeout: Optional[float] = None + gen: abc.PQGen[abc.RV], fileno: int, interval: Optional[float] = None ) -> abc.RV: ... # Copy support diff --git a/psycopg_c/psycopg_c/_psycopg/waiting.pyx b/psycopg_c/psycopg_c/_psycopg/waiting.pyx index 3a6cc6e25..d11a2d9c0 100644 --- a/psycopg_c/psycopg_c/_psycopg/waiting.pyx +++ b/psycopg_c/psycopg_c/_psycopg/waiting.pyx @@ -177,20 +177,20 @@ finally: cdef int wait_c_impl(int fileno, int wait, float timeout) except -1 -def wait_c(gen: PQGen[RV], int fileno, timeout = None) -> RV: +def wait_c(gen: PQGen[RV], int fileno, interval = None) -> RV: """ Wait for a generator using poll or select. """ - cdef float ctimeout + cdef float cinterval cdef int wait, ready cdef PyObject *pyready - if timeout is None: - ctimeout = -1.0 + if interval is None: + cinterval = -1.0 else: - ctimeout = float(timeout) - if ctimeout < 0.0: - ctimeout = -1.0 + cinterval = float(interval) + if cinterval < 0.0: + cinterval = -1.0 send = gen.send @@ -198,7 +198,7 @@ def wait_c(gen: PQGen[RV], int fileno, timeout = None) -> RV: wait = next(gen) while True: - ready = wait_c_impl(fileno, wait, ctimeout) + ready = wait_c_impl(fileno, wait, cinterval) if ready == READY_NONE: pyready = PY_READY_NONE elif ready == READY_R: diff --git a/tests/test_waiting.py b/tests/test_waiting.py index c4d8915e8..15c331ac3 100644 --- a/tests/test_waiting.py +++ b/tests/test_waiting.py @@ -28,11 +28,11 @@ waitfns = [ ] events = ["R", "W", "RW"] -timeouts = [pytest.param({}, id="blank")] -timeouts += [pytest.param({"timeout": x}, id=str(x)) for x in [None, 0, 0.2, 10]] +intervals = [pytest.param({}, id="blank")] +intervals += [pytest.param({"interval": x}, id=str(x)) for x in [None, 0, 0.2, 10]] -@pytest.mark.parametrize("timeout", timeouts) +@pytest.mark.parametrize("timeout", intervals) def test_wait_conn(dsn, timeout): gen = generators.connect(dsn) conn = waiting.wait_conn(gen, **timeout) @@ -63,7 +63,7 @@ def test_wait_ready(waitfn, event): @pytest.mark.parametrize("waitfn", waitfns) -@pytest.mark.parametrize("timeout", timeouts) +@pytest.mark.parametrize("timeout", intervals) def test_wait(pgconn, waitfn, timeout): waitfn = getattr(waiting, waitfn) @@ -104,7 +104,7 @@ def test_wait_timeout(pgconn, waitfn): except StopIteration as ex: return ex.value - (res,) = waitfn(gen_wrapper(), pgconn.socket, timeout=0.1) + (res,) = waitfn(gen_wrapper(), pgconn.socket, interval=0.1) assert res.status == ExecStatus.TUPLES_OK ds = [t1 - t0 for t0, t1 in zip(ts[:-1], ts[1:])] assert len(ds) >= 5 @@ -146,7 +146,7 @@ def test_wait_large_fd(dsn, fname): f.close() -@pytest.mark.parametrize("timeout", timeouts) +@pytest.mark.parametrize("timeout", intervals) @pytest.mark.anyio async def test_wait_conn_async(dsn, timeout): gen = generators.connect(dsn)