[Bug] Python SDK: ModelClient polling loops lack timeout and cancellation support
- Dominant language
- Python
- Stars
- 485
- Forks
- 81
- Avg merge
- 16h 12m
- Merged PRs (30d)
- 8
Description
**Bug Description**
`ModelClient` 中的轮询循环 (`while True`) 缺少超时机制和取消支持,可能导致程序永久阻塞。
在 PR #492 (TypeScript SDK) 的 Code Review 中,Reviewer @dengwx2026 指出:
> **Add cancellation support**: `ModelClient` polling loops (`while(true)`) need `AbortController` or timeout mechanisms to avoid blocking forever.
经调研,该问题源自 Python SDK 的原始设计。
**Steps to Reproduce**
1. 创建 `ModelClient` 实例
2. 调用 `anti_call_llm(index=0)` 方法
3. 如果日志文件不存在或永远没有请求写入,程序将无限阻塞
**Expected Behavior**
- 应该支持超时参数,允许设置最大等待时间
- 应该支持取消操作(如 `asyncio.CancelledError`)
- 在超时或取消时抛出明确的异常
**Actual Behavior**
- 程序在 `while True` 循环中无限等待
- 无超时机制
- 无取消支持
- 无法中断阻塞状态
**Error Logs**
无错误日志输出,程序静默阻塞。
**Environment Information**
- **OS**: macOS 14.0 (Darwin 23.6.0)
- **Python Version**: 3.14.2
- **ROCK Version**: dev (feature/ts-sdk branch)
- **Installation Method**: source installation
- **Docker Version**: N/A
- **Deployment Type**: local
**ROCK Configuration**
- **Runtime Environment Type**: N/A
- **Sandbox Image**: N/A
- **Resource Allocation**: N/A
**Component Affected**
- [ ] Sandbox
- [ ] Actions
- [ ] Deployments
- [x] SDK & API
- [ ] Envhub
- [ ] CLI
- [ ] Performance & Optimization
- [ ] Documentation & Examples
---
**Additional Context**
问题代码位于 `sdk/model/client.py`:
1. `pop_request` 方法 (第67-76行)
2. `wait_for_first_request` 方法 (第107-120行)
**Suggested Solutions**
```python
# 方案一:添加超时参数
async def pop_request(self, index: int, timeout: float | None = None) -> str:
start_time = time.monotonic()
while True:
if timeout is not None and time.monotonic() - start_time > timeout:
raise TimeoutError(f"pop_request timed out after {timeout} seconds")
# ... rest of the logic
```
```python
# 方案二:支持 asyncio.CancelledError
async def pop_request(self, index: int) -> str:
while True:
try:
# ... existing logic
await asyncio.sleep(1)
except asyncio.CancelledError:
logger.info("pop_request cancelled")
raise
```
```python
# 方案三:调用方使用 asyncio.wait_for 包装
request = await asyncio.wait_for(client.pop_request(index), timeout=30.0)
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in sdk/model/client.py with pop_request (lines 67–76) and wait_for_first_request (lines 107–120), then trace how anti_call_llm(index=0) reaches those polling loops. Clarify the timeout and cancellation behavior against the three suggested approaches. Done means the loops no longer block forever and timeout or cancellation produces a clear exception.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100