Conversation
| response_stream = response_iterator.__aiter__() | ||
| while True: | ||
| if terminal_read_task is None: | ||
| response = await _read_rpc_response(response_stream) |
There was a problem hiding this comment.
[P2] trace 关闭(client_span=None)时 settlement 路径首次在无 span 下激活,需确认对 None 的处理
补丁将条件由 client_span is not None 改为 client_span is not None or terminal_seen(补丁 + 行 1087-1089),同时 client_settlement_abandoned 的创建条件改为 client_span is not None or use_fetch_response(补丁 + 行 1053)。当 trace 关闭但 use_fetch_response=True 时,terminal_seen 为真会使 _engine_reported_finished 块执行,settlement task 可能在 client_span=None 时被创建。若该块内创建 client_settlement_task 或 _settle_client_span_after_rpc 未对 client_span=None 做防护,会触发 AttributeError(补丁内看不到该块函数体,无法确认)。
建议:确认 _engine_reported_finished 块内 settlement task 的创建处及 _settle_client_span_after_rpc 对 client_span=None 的处理;若未防护,补充 None 判断或仅在 client_span is not None 时创建 settlement task。
评审版本:69e9a58c71f8
| for close_at_frame in (False, True): | ||
| with self.subTest( | ||
| trace_enabled=trace_enabled, close_at_frame=close_at_frame | ||
| ): |
There was a problem hiding this comment.
[P2] 缺少 trace_enabled=False 且 RPC 延迟错误的测试覆盖
test_fetch_response_terminal_read_preserves_late_rpc_errors 仅以默认 trace_enabled=True 循环 status,未覆盖 client_span 为 None 时(trace 关闭)的延迟 RPC 错误路径;而本次改动专门扩展了 client_span is None 或 terminal_seen 的结算逻辑,该分支缺少回归测试。
建议:为该测试增加 trace_enabled=False 的 subTest,验证 trace 关闭时 late RPC error 仍被正确处理,或明确该场景不要求传播错误。
评审版本:69e9a58c71f8
| @@ -1186,14 +1212,14 @@ async def enqueue( | |||
| ) | |||
There was a problem hiding this comment.
[P2] terminal_read_task 在 finally 及异常路径中未被取消或等待,异常可能未被消费
finally 块(补丁 + 行 1214-1219)仅调用 client_settlement_abandoned.set(),从不 cancel/await terminal_read_task;而 _read_rpc_response(补丁 + 行 129-133)只捕获 StopAsyncIteration,服务器以非 OK 状态 abort 时(测试 test_fetch_response_terminal_read_preserves_late_rpc_errors 覆盖 CANCELLED/DEADLINE_EXCEEDED/INTERNAL)AioRpcError 会进入 terminal_read_task。若消费者在 finished 帧后立即关闭生成器(GeneratorExit),该 task 脱离事件循环,异常仅能靠 add_done_callback(_consume_settlement_task)(补丁 + 行 1095-1096)消费;若该回调未显式调用 task.exception()/result(),会产生 “Task exception was never retrieved” 告警并可能滞留资源。
建议:在 finally 中显式处理 terminal_read_task:若未完成则取消或确保其异常被消费(例如在 _consume_settlement_task 内无条件取出 exception),避免未检索异常告警;并补充注释说明该 task 的生命周期归属。
评审版本:69e9a58c71f8
| self.assertIsInstance(result, asyncio.CancelledError) | ||
| servicer.release.set() | ||
| expected = status if finished else StatusCode.CANCELLED | ||
| for call in calls: |
There was a problem hiding this comment.
[P2] 测试未覆盖 close_at_frame=True 与服务端错误状态的组合
test_fetch_response_terminal_read_survives_consumer_teardown 仅覆盖 StatusCode.OK 下的 trace_enabled×close_at_frame 四种组合;test_fetch_response_terminal_read_preserves_late_rpc_errors 使用默认参数(close_at_frame=False)覆盖 CANCELLED/DEADLINE_EXCEEDED/INTERNAL。缺少"消费者在 finished frame 处 aclose + 服务端随后 abort"的组合,而该组合正是本 PR 核心修复点(terminal read 在消费者关闭后仍需保留迟到错误并通过 done callback 正确结算 span)的关键路径,也是验证 _consume_settlement_task 复用是否正确的唯一场景。
建议:在 test_fetch_response_terminal_read_preserves_late_rpc_errors 中增加 close_at_frame=True(及 trace_enabled=False)的子测试,验证消费者关闭后 terminal_read_task 抛出的迟到 RPC 错误仍被正确结算到 span(status=ERROR、end_count=1)。
评审版本:69e9a58c71f8
PR #1438 评审:未发现阻塞项,等待人工审核
无阻塞项非阻塞发现
自动代码评审 · head |
rtp-llm-review-bot
left a comment
There was a problem hiding this comment.
lgtm ready to ci
评审版本:69e9a58c71f80e3d429f74d6132096b6c2482f79
Master BATCH + P/D requests can complete successfully while the FetchResponse CLIENT span reports CANCELLED: upstream teardown cancels the pending gRPC EOF read after the terminal application frame.
Transfer that read to a shielded task before yielding the terminal frame, and finalize the span using the actual RPC status. Preserve cancellation before completion, late RPC errors, and bounded cleanup. Use the same transport cleanup with tracing disabled.
Validation: