fix: 修复多个关键生产问题 — 数据库兼容性、安全超时与 HTTP 响应体泄漏 - #4853
Conversation
本次提交包含以下修复:
**数据库兼容性**
- 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>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughRelay 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. ChangesDatabase Configuration and Initialization
Response Body Resource Management
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (11)
common/init.gomodel/log.gomodel/main.gorelay/channel/replicate/adaptor.gorelay/channel/task/ali/adaptor.gorelay/channel/task/doubao/adaptor.gorelay/channel/task/gemini/adaptor.gorelay/channel/task/hailuo/adaptor.gorelay/channel/task/jimeng/adaptor.gorelay/channel/task/sora/adaptor.gorelay/channel/task/vertex/adaptor.go
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.
摘要
本次 PR 修复了多个关键生产问题:
数据库兼容性
model/log.go:将ifnull()替换为coalesce(),修复 PostgreSQL 兼容性问题。PostgreSQL 不支持IFNULL函数,使用标准 SQL 的COALESCE替代。model/main.go:为 SQLite 数据库连接添加PRAGMA journal_mode=WAL、PRAGMA busy_timeout=5000和PRAGMA synchronous=NORMAL。解决高并发场景下 SQLite 数据库锁死(database is locked)问题(ref: [Bug] SQLite relay billing can cascade from SQLITE_BUSY into transaction errors and 403s #4266、[Bug] SQLite relay billing can cascade from SQLITE_BUSY into "cannot start a transaction within a transaction" #4263)。超时安全
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 行
测试
ifnull()→coalesce()在 SQLite/MySQL/PostgreSQL 上均有相同行为defer resp.Body.Close()在所有异常路径(包括 panic)中均能正确释放资源🤖 Generated with Claude Code Best
Summary by CodeRabbit
Bug Fixes
Performance
Bug Fixes