.. warning::
- The `!cancel()` method has a few shortcomings:
+ The `!cancel()` method is implemented using the :pq:`PQcancel`
+ function, which is deprecated since PostgreSQL 17, and has a few
+ shortcomings:
- it is blocking even on async connections,
- it `might use an insecure connection`__ even if the original
def cancel(self) -> None:
"""Cancel the current operation on the connection."""
- if self._should_cancel():
- self._try_cancel(self.pgconn)
+ if not self._should_cancel():
+ return
+
+ # Don't fail cancelling (which might happen on connection closing) to
+ # avoid clobbering eventual exceptions with ours, which is less important.
+ try:
+ c = self.pgconn.get_cancel()
+ c.cancel()
+ except Exception as ex:
+ logger.warning("couldn't try to cancel query: %s", str(ex))
def _should_cancel(self) -> bool:
"""Check whether the current command should actually be cancelled when
)
return True
- @classmethod
- def _try_cancel(cls, pgconn: "PGconn") -> None:
- """Try to cancel the current command using a PGcancel object,
- which is deprecated since libpq 17.
- """
- try:
- # Can fail if the connection is closed
- c = pgconn.get_cancel()
- except Exception as ex:
- logger.warning("couldn't try to cancel query: %s", ex)
- else:
- c.cancel()
-
def _cancel_gen(self) -> PQGenConn[None]:
try:
cancel_conn = self.pgconn.cancel_conn()