(self, timeout: float)
| 246 | sleep(attempt.delay) |
| 247 | |
| 248 | def _getconn_unchecked(self, timeout: float) -> CT: |
| 249 | # Critical section: decide here if there's a connection ready |
| 250 | # or if the client needs to wait. |
| 251 | with self._lock: |
| 252 | if not (conn := self._get_ready_connection(timeout)): |
| 253 | # No connection available: put the client in the waiting queue |
| 254 | t0 = monotonic() |
| 255 | pos: WaitingClient[CT] = WaitingClient() |
| 256 | self._waiting.append(pos) |
| 257 | self._stats[self._REQUESTS_QUEUED] += 1 |
| 258 | |
| 259 | # If there is space for the pool to grow, let's do it |
| 260 | self._maybe_grow_pool() |
| 261 | |
| 262 | # If we are in the waiting queue, wait to be assigned a connection |
| 263 | # (outside the critical section, so only the waiting client is locked) |
| 264 | if not conn: |
| 265 | try: |
| 266 | conn = pos.wait(timeout=timeout) |
| 267 | except CLIENT_EXCEPTIONS: |
| 268 | if pos.conn: |
| 269 | self.run_task(ReturnConnection(self, pos.conn, from_getconn=True)) |
| 270 | self._stats[self._REQUESTS_ERRORS] += 1 |
| 271 | raise |
| 272 | finally: |
| 273 | t1 = monotonic() |
| 274 | self._stats[self._REQUESTS_WAIT_MS] += int(1000.0 * (t1 - t0)) |
| 275 | |
| 276 | # Tell the connection it belongs to a pool to avoid closing on __exit__ |
| 277 | # Note that this property shouldn't be set while the connection is in |
| 278 | # the pool, to avoid to create a reference loop. |
| 279 | conn._pool = self |
| 280 | return conn |
| 281 | |
| 282 | def _get_ready_connection(self, timeout: float | None) -> CT | None: |
| 283 | """Return a connection, if the client deserves one.""" |
no test coverage detected