Skip to content

fix: 修复多个关键生产问题 — 数据库兼容性、安全超时与 HTTP 响应体泄漏 - #4853

Closed
Evsdrg wants to merge 2 commits into
QuantumNous:mainfrom
Evsdrg:fix/critical-production-issues
Closed

fix: 修复多个关键生产问题 — 数据库兼容性、安全超时与 HTTP 响应体泄漏#4853
Evsdrg wants to merge 2 commits into
QuantumNous:mainfrom
Evsdrg:fix/critical-production-issues

Conversation

@Evsdrg

@Evsdrg Evsdrg commented May 14, 2026

Copy link
Copy Markdown

摘要

本次 PR 修复了多个关键生产问题:

数据库兼容性

超时安全

  • common/init.go:将 RELAY_TIMEOUT 默认值从 0(无超时)改为 60 秒,防止上游无响应时 HTTP 连接永久占用导致连接池耗尽。

HTTP 响应体泄漏

  • relay/channel/replicate/adaptor.go:使用 defer resp.Body.Close() 替代 _ = resp.Body.Close()
  • relay/channel/task/{sora,gemini,vertex,hailuo,doubao,jimeng,ali}/adaptor.go:同上,确保即使发生 panic 也能正确释放 HTTP 连接,防止高并发下文件描述符耗尽。

变更文件

11 个文件,+35 行,-11 行

测试

  • 所有变更均为独立的 Bug 修复,无破坏性改动
  • ifnull()coalesce() 在 SQLite/MySQL/PostgreSQL 上均有相同行为
  • SQLite WAL PRAGMA 设置使用 SysLog 记录失败,不会阻塞数据库初始化
  • defer resp.Body.Close() 在所有异常路径(包括 panic)中均能正确释放资源

🤖 Generated with Claude Code Best

Summary by CodeRabbit

  • Bug Fixes

    • Ensured HTTP responses are reliably closed across channels to prevent resource leaks.
    • Corrected token summation in logs so null totals are treated as zero.
  • Performance

    • Applied SQLite runtime optimizations (WAL, timeout and synchronous settings) for better concurrency and stability.
  • Bug Fixes

    • Increased default relay timeout to 60 seconds for improved request stability.

Review Change Stack

本次提交包含以下修复:

**数据库兼容性**
- model/log.go: 将 ifnull() 替换为 coalesce(),修复 PostgreSQL 兼容性问题。
  PostgreSQL 不支持 IFNULL 函数,使用标准 SQL 的 COALESCE 替代。
- model/main.go: 为 SQLite 添加 WAL 模式、busy_timeout 和 synchronous PRAGMA。
  解决高并发场景下 SQLite 数据库锁死(database is locked)问题。
  WAL 模式允许读写并发,busy_timeout 避免立即返回错误,
  synchronous=NORMAL 在性能和安全之间取得平衡。

**超时安全**
- common/init.go: 将 RELAY_TIMEOUT 默认值从 0 改为 60 秒。
  默认值 0 意味着 HTTP 请求无超时,上游无响应时会永久占用连接,
  最终导致连接池耗尽。

**HTTP 响应体泄漏**
- relay/channel/replicate/adaptor.go: 使用 defer resp.Body.Close()
- relay/channel/task/{sora,gemini,vertex,hailuo,doubao,jimeng,ali}/adaptor.go:
  将 _ = resp.Body.Close() 改为 defer resp.Body.Close(),确保即使发生 panic
  也能正确释放 HTTP 连接,防止高并发下文件描述符耗尽。

Co-Authored-By: deepseek-v4-pro[1m] <deepseek-ai@claude-code-best.win>
@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 035d12e3-8db1-415a-add6-cbc928a88fb1

📥 Commits

Reviewing files that changed from the base of the PR and between a8b8ed2 and f5e0f20.

📒 Files selected for processing (1)
  • model/main.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • model/main.go

Walkthrough

Relay timeout default set to 60s; InitDB and InitLogDB apply SQLite PRAGMAs when using SQLite; SumUsedToken uses coalesce; multiple relay replicate/task adaptors now defer closing HTTP response bodies to ensure cleanup on all return paths.

Changes

Database Configuration and Initialization

Layer / File(s) Summary
Relay timeout default and SQLite configuration
common/init.go, model/main.go, model/log.go
RelayTimeout default changed from 0 to 60; InitDB and InitLogDB run SQLite PRAGMAs (journal_mode=WAL, busy_timeout=5000, synchronous=NORMAL) with warning logs on failure; SumUsedToken switches SQL aggregation from ifnull to coalesce.

Response Body Resource Management

Layer / File(s) Summary
Deferred response body closure across relay adaptors
relay/channel/replicate/adaptor.go, relay/channel/task/ali/adaptor.go, relay/channel/task/doubao/adaptor.go, relay/channel/task/gemini/adaptor.go, relay/channel/task/hailuo/adaptor.go, relay/channel/task/jimeng/adaptor.go, relay/channel/task/sora/adaptor.go, relay/channel/task/vertex/adaptor.go
DoResponse implementations now defer resp.Body.Close() immediately before reading the body, replacing explicit post-read closes so the response body is closed on all return paths (including read errors).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • QuantumNous/new-api#2141: Overlaps changes to the Ali task adaptor's TaskAdaptor.DoResponse and its response-body closure behavior.
  • QuantumNous/new-api#1792: Related to initial Vertex adaptor changes; this PR refactors Vertex DoResponse to defer response-body closure.

Suggested reviewers

  • Calcium-Ion

Poem

🐇 I hop through code with nimble paws,

Deferring closes, mending flaws.
Timeouts set and pragmas sung,
Coalesce stitches sums as one.
No leaks remain — the build hums on.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 directly addresses the main changes: database compatibility fixes, timeout safety, and HTTP response body leaks across multiple files.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@model/main.go`:
- Around line 250-260: The PRAGMA block is currently gated by common.UsingSQLite
(main DB) so InitLogDB may skip or wrongly log warnings; change the guard to
check the log DB type instead by using common.LogSqlType ==
common.DatabaseTypeSQLite before executing PRAGMAs on sqlDB (the block that
calls sqlDB.Exec and logs via common.SysLog), ensuring PRAGMAs are only applied
when the LOG_DB is SQLite and avoiding false warnings when the log DB is
MySQL/Postgres.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 417fbdea-03bd-4c10-84f2-600c967cf2fd

📥 Commits

Reviewing files that changed from the base of the PR and between 18282e6 and a8b8ed2.

📒 Files selected for processing (11)
  • common/init.go
  • model/log.go
  • model/main.go
  • relay/channel/replicate/adaptor.go
  • relay/channel/task/ali/adaptor.go
  • relay/channel/task/doubao/adaptor.go
  • relay/channel/task/gemini/adaptor.go
  • relay/channel/task/hailuo/adaptor.go
  • relay/channel/task/jimeng/adaptor.go
  • relay/channel/task/sora/adaptor.go
  • relay/channel/task/vertex/adaptor.go

Comment thread model/main.go Outdated
CodeRabbit pointed out that InitLogDB's SQLite PRAGMA block checked
common.UsingSQLite (main DB flag) instead of the log DB type flag.
Changed to common.LogSqlType == common.DatabaseTypeSQLite to ensure
PRAGMAs are only applied when the log database is actually SQLite.
@seefs001 seefs001 closed this May 17, 2026
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.

2 participants