googleapis / googleapis/google-cloud-python
auth: AsyncAuthorizedSession.request leaks response across retry attempts
- 主要语言
- Python
- 星标
- 5.4k
- 派生
- 1.8k
- 平均合并
- 2 天 23 小时
- 30 天内合并 PR
- 123
描述
In `google.auth.aio.transport.sessions.AsyncAuthorizedSession.request` (`packages/google-auth/google/auth/aio/transport/sessions.py:339-347`), the retry loop reassigns `response = await with_timeout(...)` across retry attempts without closing the previous response.
If the response payload hasn't reached EOF before the next retry fires (e.g., with chunked or streaming responses), `aiohttp` keeps the socket checked out in `connector._acquired`. The transport protocol's internal EOF callback holds a bound reference to `ClientResponse._response_eof`, which prevents Python's garbage collector from cleaning up the orphaned response while the connection is waiting for data. Under concurrency, multiple requests retrying against a degraded endpoint can quickly burn through the connector pool (`limit=100`) and block other outgoing requests across the session.
### Proposed Fix
Close any previous response before kicking off the next retry attempt, matching the pattern already used in `sessions.py:L501-L518`:
```python
response = None
async for _ in retries:
if response is not None and hasattr(response, "close"):
try:
res = response.close()
if inspect.isawaitable(res):
await res
except Exception:
pass
response = await with_timeout(
self._auth_request(
url, method, data, request_headers, actual_timeout, **kwargs
)
)
if response.status_code not in transport.DEFAULT_RETRYABLE_STATUS_CODES:
break
```
Unit tests should check that when a retryable status code (like a 503) is followed by a 200, `close()` is awaited on the initial response before the retry runs.
贡献指南
调研方向
Start in packages/google-auth/google/auth/aio/transport/sessions.py at AsyncAuthorizedSession.request, then compare its retry loop with the cleanup pattern at lines 501-518. Add unit coverage for a retryable 503 followed by a 200, verifying that the initial response's close() is awaited before the retry proceeds.
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- networking
- Issue 类型
- 缺陷
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 活跃度
- 活跃
- 描述清晰度
- 描述清楚
- 新手友好度
- 88/100