| 193 | return proxy |
| 194 | |
| 195 | async def release(self, timeout: Optional[float]) -> None: |
| 196 | if self._in_use is None: |
| 197 | raise exceptions.InternalClientError( |
| 198 | 'PoolConnectionHolder.release() called on ' |
| 199 | 'a free connection holder') |
| 200 | |
| 201 | if self._con.is_closed(): |
| 202 | # When closing, pool connections perform the necessary |
| 203 | # cleanup, so we don't have to do anything else here. |
| 204 | return |
| 205 | |
| 206 | self._timeout = None |
| 207 | |
| 208 | if self._con._protocol.queries_count >= self._max_queries: |
| 209 | # The connection has reached its maximum utilization limit, |
| 210 | # so close it. Connection.close() will call _release(). |
| 211 | await self._con.close(timeout=timeout) |
| 212 | return |
| 213 | |
| 214 | if self._generation != self._pool._generation: |
| 215 | # The connection has expired because it belongs to |
| 216 | # an older generation (Pool.expire_connections() has |
| 217 | # been called.) |
| 218 | await self._con.close(timeout=timeout) |
| 219 | return |
| 220 | |
| 221 | try: |
| 222 | budget = timeout |
| 223 | |
| 224 | if self._con._protocol._is_cancelling(): |
| 225 | # If the connection is in cancellation state, |
| 226 | # wait for the cancellation |
| 227 | started = time.monotonic() |
| 228 | await compat.wait_for( |
| 229 | self._con._protocol._wait_for_cancellation(), |
| 230 | budget) |
| 231 | if budget is not None: |
| 232 | budget -= time.monotonic() - started |
| 233 | |
| 234 | if self._pool._reset is not None: |
| 235 | async with compat.timeout(budget): |
| 236 | await self._con._reset() |
| 237 | await self._pool._reset(self._con) |
| 238 | else: |
| 239 | await self._con.reset(timeout=budget) |
| 240 | except (Exception, asyncio.CancelledError) as ex: |
| 241 | # If the `reset` call failed, terminate the connection. |
| 242 | # A new one will be created when `acquire` is called |
| 243 | # again. |
| 244 | try: |
| 245 | # An exception in `reset` is most likely caused by |
| 246 | # an IO error, so terminate the connection. |
| 247 | self._con.terminate() |
| 248 | finally: |
| 249 | raise ex |
| 250 | |
| 251 | # Free this connection holder and invalidate the |
| 252 | # connection proxy. |