Beispiel #1
0
    async def _connect(self) -> AsyncConnection[Any]:
        """Return a new connection configured for the pool."""
        self._stats[self._CONNECTIONS_NUM] += 1
        t0 = monotonic()
        try:
            conn: AsyncConnection[Any]
            conn = await self.connection_class.connect(self.conninfo,
                                                       **self.kwargs)
        except Exception:
            self._stats[self._CONNECTIONS_ERRORS] += 1
            raise
        else:
            t1 = monotonic()
            self._stats[self._CONNECTIONS_MS] += int(1000.0 * (t1 - t0))

        conn._pool = self

        if self._configure:
            await self._configure(conn)
            status = conn.pgconn.transaction_status
            if status != TransactionStatus.IDLE:
                nstatus = TransactionStatus(status).name
                raise e.ProgrammingError(
                    f"connection left in status {nstatus} by configure function"
                    f" {self._configure}: discarded")

        # Set an expiry date, with some randomness to avoid mass reconnection
        conn._expire_at = monotonic() + self._jitter(self.max_lifetime, -0.05,
                                                     0.0)
        return conn
Beispiel #2
0
    def _connect(self) -> Connection[Any]:
        """Return a new connection configured for the pool."""
        self._stats[self._CONNECTIONS_NUM] += 1
        t0 = monotonic()
        try:
            conn: Connection[Any]
            conn = self.connection_class.connect(self.conninfo, **self.kwargs)
        except Exception:
            self._stats[self._CONNECTIONS_ERRORS] += 1
            raise
        else:
            t1 = monotonic()
            self._stats[self._CONNECTIONS_MS] += int(1000.0 * (t1 - t0))

        conn._pool = self

        if self._configure:
            self._configure(conn)
            status = conn.pgconn.transaction_status
            if status != TransactionStatus.IDLE:
                sname = TransactionStatus(status).name
                raise e.ProgrammingError(
                    f"connection left in status {sname} by configure function"
                    f" {self._configure}: discarded")

        # Set an expiry date, with some randomness to avoid mass reconnection
        self._set_connection_expiry_date(conn)
        return conn
Beispiel #3
0
    def _reset_connection(self, conn: Connection[Any]) -> None:
        """
        Bring a connection to IDLE state or close it.
        """
        status = conn.pgconn.transaction_status
        if status == TransactionStatus.IDLE:
            pass

        elif status in (TransactionStatus.INTRANS, TransactionStatus.INERROR):
            # Connection returned with an active transaction
            logger.warning("rolling back returned connection: %s", conn)
            try:
                conn.rollback()
            except Exception as ex:
                logger.warning(
                    "rollback failed: %s: %s. Discarding connection %s",
                    ex.__class__.__name__,
                    ex,
                    conn,
                )
                conn.close()

        elif status == TransactionStatus.ACTIVE:
            # Connection returned during an operation. Bad... just close it.
            logger.warning("closing returned connection: %s", conn)
            conn.close()

        if not conn.closed and self._reset:
            try:
                self._reset(conn)
                status = conn.pgconn.transaction_status
                if status != TransactionStatus.IDLE:
                    nstatus = TransactionStatus(status).name
                    raise e.ProgrammingError(
                        f"connection left in status {nstatus} by reset function"
                        f" {self._reset}: discarded"
                    )
            except Exception as ex:
                logger.warning(f"error resetting connection: {ex}")
                conn.close()