Skip to content

feat(relay): add opt-in HTTP/2 health checks - #8059

Open
Perfecto23 wants to merge 1 commit into
QuantumNous:mainfrom
Perfecto23:feat/relay-http2-health-check
Open

Perfecto23 wants to merge 1 commit into
QuantumNous:mainfrom
Perfecto23:feat/relay-http2-health-check

Conversation

@Perfecto23

@Perfecto23 Perfecto23 commented Oct 27, 2026 •

Copy link
Copy Markdown

Agent

  • Tool: OpenAI Codex;代码与说明由 AI 辅助生成,已逐项复核。
  • Tool version: 桌面宿主未向会话提供版本号。
  • Model (full id): 宿主标识为 GPT-6-Astra Xhigh。
  • Host (CLI / IDE / GitHub coding agent / other): Codex desktop。
  • Date (UTC): 2026-10-27。

Links

User request

基于实际遇到的 Azure 长请求超时与断流问题,完善 New API 的上游连接健康探测和故障恢复。复用现有传输层机制,保持正常慢响应、代理和连接分片的兼容性,并通过可复现的修改前后对照验证效果。

公开说明故障现象、已确认的原因及仍待验证的部分,提交范围聚焦、便于维护者审查的上游改动。

Out of scope — refuse

  • Matched: no。范围为官方上游的共享 HTTP Transport,涉及直连与代理连接的健康探测。
  • If yes, what was told to the user: 不适用。

Open gate — do not open unless all are satisfied

  • Out of scope (including pass-through-only forwarding): no。
  • Usage / configuration / integration (answered instead of opening): no;当前代码没有该探测配置。
  • Required issue facts present without invention: yes;关联现有功能请求 feat: 配置 HTTP/2 PING 保活机制,防止空闲连接被中间设备 RST #5308。
  • Verification is actual commands or steps and observed results, not only go build or tests passed: yes。
  • Body is short and factual; no unfiltered AI-generated text: yes。
  • Open: yes。
  • If no, what was told to the user: 不适用。

Kind

  • Bug fix
  • New feature
  • Performance / refactor
  • Docs
  • Other

Issue facts

  • Actual behavior: feat: 配置 HTTP/2 PING 保活机制,防止空闲连接被中间设备 RST #5308 报告连接经过中间设备后失效,复用时出现 connection reset by peer / HTTP 500。
  • Impact: 请求失败;存活状态无法及时确认。
  • Frequency: 该 issue 描述按失效连接复用触发,未提供统计频率。
  • Evidence that the problem is in new-api rather than the client or upstream: newRelayHTTPTransport() 启用 HTTP/2,但未配置连接健康探测;本地真实 HTTP/2 对端停止应答 PING 时可复现等待客户端超时。
  • Applicable types: relay / deployment;共享上游 Transport,HTTP/2,包含直连、代理和连接分片。billing / frontend 不适用。

Change

新增两个启动环境变量,通过 Go 标准库 http.HTTP2Config 配置共享 Transport:RELAY_HTTP2_PING_IDLE_TIMEOUT=0 默认保持现有行为,正数启用探测;RELAY_HTTP2_PING_TIMEOUT=15 控制等待应答的时间。超大值在转成 time.Duration 前截断,PING 超时非正数使用 Go 默认值。

实际使用中,我们在 rc.44 的官方 Azure 渠道遇到过间歇性 408/5xx,以及发出 SSE 心跳后错误被客户端读成空流的情况。升级 rc.47 后,用 OpenAI Python SDK 2.48.0 验证了 #7857 的错误交付修复。本 PR 补充连接健康探测;现场 Azure 408 与失效 HTTP/2 连接之间的因果关系仍待验证。

Research

Duplicate / prior art

Docs and code

  • 官方文档:现有部署和超时配置入口。
  • DeepWiki 环境变量:用于定位现有配置;具体实现以当前源码为准。
  • README / repo docs: README.md 的贡献要求、AGENTS.md、.env.example;按 .agents/github/PR.md 填写本说明。
  • Code paths: common.InitEnv → newRelayHTTPTransport → 直连 / 代理 / 分片客户端;Go HTTP2Config 区分连接探测与整次请求超时。

Alternatives considered

  • Option A: 全局默认开启固定间隔探测,会改变所有部署的连接行为。
  • Option B: 现有环境变量机制下按需开启(采用)。
  • Why this approach: 保留部署兼容性,复用标准库和共享 Transport 工厂;SSE 心跳与 IdleConnTimeout 各自保留原职责。

Files

Path Why
common/constants.go, common/init.go 声明并读取两个配置值
service/http_client.go 为共享 Transport 配置探测
.env.example 默认值、单位和启用语义
service/http_client_transport_test.go 真实 HTTP/2 帧回归;现有代理、分片与 HTTP/1.1 用例启用探测配置后继续验证

Behavior

  • Before: 静默失效的 HTTP/2 连接可能一直占住正在读取的响应,直到其他超时触发。
  • After: 启用后,无入站帧达到配置间隔即发送 PING;应答超时关闭连接,当前读取收到错误,后续请求建立新连接。正常应答的慢响应继续完成。
  • Explicit non-goals / leftover work: Azure 应用层 408、Chat→Responses 缓冲转换以及请求重试策略保持各自现有行为。

Verification

  • Commands and results(Go 1.26.10,macOS arm64):
    • go test ./service -run '^TestRelayHTTP2HealthCheck$' -count=1 -v:关闭探测时等待客户端超时且无 PING;正常对端应答两次 PING 后返回完整响应;失效对端触发 http2: client connection lost,下一请求通过新连接完成。
    • 使用 go test -overlay 仅将 service/http_client.go 替换为 base 版本再运行同一测试:开启探测的两个用例均等待到客户端超时,关闭探测用例通过。
    • go test -race ./service -run 'TestRelayHTTP2HealthCheck|TestAutoOneShard|TestFourShard|TestForcedHTTP1|Test.*Proxy|TestCloseIdleConnections' -count=1:通过;HTTP/1.1、代理、分片和缓存重建行为保持。
    • go test ./service -count=1、根模块 GOWORK=off go vet ./... / go build ./...、分别在 relaykit/ 和 tokenkit/ 运行 GOWORK=off go test ./...:通过。根构建按 CI 建立忽略的前端 embed 占位文件。
    • make test:根模块仅 advancedcustom/TestAdaptorMasksDialedHostsInDialFailure/channel_proxy_host 失败;在未修改的 base 34003e9c2 单独运行同一用例得到相同失败:预期代理域名,实际 unexpected EOF。两个独立模块已分别补跑通过。
  • Manual steps and observed result: HTTP/2 对端通过真实 TLS 连接收发帧,选择应答或丢弃 PING;失效响应保留已收到的 start,后续新请求得到 startend。
  • UI: 无 UI 改动。
  • Tests added or updated: 三个行为场景集中在现有 Transport 测试文件。
  • Databases / providers / platforms exercised: 本地 TLS / HTTP/2 对端;无数据库改动。
  • Not verified: 本补丁尚未部署到真实 Azure 流量;本机全量测试中的既有 WebSocket 用例失败如上。

Risks

  • Failure modes: 启用后,过短的等待时间或中间设备阻断 PING 应答会关闭仍有请求的连接;默认关闭,可按网络条件配置。
  • Billing / quota / auth impact: 无直接改动;已开始响应的请求仍按原错误路径结束,探测本身不重放请求。
  • Follow-ups: 在实际部署中按需开启,观察连接错误和上游请求结果。

Scope check

  • Single focused change: yes。
  • Secrets included: no。
  • Out of scope (Coding Plan / reverse-engineered channel / third-party wrapper / Codex / pass-through-only forwarding): no。

Summary by CodeRabbit

  • New Features
    • Added optional health checks for HTTP/2 connections used by the relay. They are disabled by default and can be configured with RELAY_HTTP2_PING_IDLE_TIMEOUT and RELAY_HTTP2_PING_TIMEOUT.
    • Connections that fail to acknowledge a health check are closed; slow requests can continue when their connection responds. These checks operate independently of client-facing SSE heartbeats.

@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 05fc6cca-38c7-4bbf-8fd0-698fd697f16b
Commits

Reviewing files that changed from the base of the PR and between 34003e9 and cedb012.

Files selected for processing: 5
  • .env.example
  • common/constants.go
  • common/init.go
  • service/http_client.go
  • service/http_client_transport_test.go

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The relay HTTP transport now supports configurable HTTP/2 PING health checks. Environment settings control the idle interval and acknowledgement timeout. Tests cover disabled probes, acknowledged probes, and unresponsive connections.

Changes

Relay HTTP/2 PING Health Checks

Layer / File(s) Summary
Configure relay PING timing
.env.example, common/constants.go, common/init.go
Adds settings for the idle interval and acknowledgement timeout. Environment loading defaults them to 0 and 15 seconds. The example file documents their scope and behavior.
Apply and verify relay PING probes
service/http_client.go, service/http_client_transport_test.go
When the idle interval is positive, the transport configures HTTP/2 PING timing and clamps the values. Tests cover disabled probes, acknowledged probes, and unanswered probes that cause a lost connection.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant RelayClient
  participant RelayHTTPTransport
  participant HTTP2Peer
  RelayClient->>RelayHTTPTransport: Send request
  RelayHTTPTransport->>HTTP2Peer: Send PING after idle interval
  HTTP2Peer-->>RelayHTTPTransport: Acknowledge PING
  RelayHTTPTransport-->>RelayClient: Continue response on connection
  HTTP2Peer--xRelayHTTPTransport: Withhold PING acknowledgement
  RelayHTTPTransport-->>RelayClient: Report lost connection
Loading

Possibly related issues

Suggested reviewers: calcium-ion

Merge Risk: Minimal · up to cedb0

The opt-in checks appear to reach the supported relay modes, with no actionable issue identified before merge.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surv… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "feat(relay): add opt-in HTTP/2 health checks" names the main change. The PR adds opt-in HTTP/2 PING health checks for relay upstream connections, controlled by RELAY_HTTP2_PING_IDLE_TIMEOUT…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "feat(relay): add opt-in HTTP/2 health checks" names the main change. The PR adds opt-in HTTP/2 PING health checks for relay upstream connections, controlled by RELAY_HTTP2_PING_IDLE_TIMEOUT (default 0, disabled) and RELAY_HTTP2_PING_TIMEOUT (default 15). The title is short, specific, and matches the objectives and the changed files in common/, service/http_client.go, and the transport tests.

Full details: Docstring Coverage

Explanation

Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 5 functions across 4 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks the silent stream,
A PING goes out to test the beam.
If answered, slow replies can stay,
If not, the link gives way.
Fresh paths await the next request,
And carrots crown the health-check quest.

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant