2 Commits

Author SHA1 Message Date
杭州明婳科技 6730f12cd6 test(database): H-db-1 补齐行为闭环 + 修复 gorm.Open automatic ping
上一提交(72ea01d)修了 4 条 pingWithTimeout 路径,但行为验证有缺口:
启动 ping 路径仅代码审查、Redis HealthCheck 仅推断、无 App 级端到端。
补齐过程发现并修复了 H-db-1 的真正根因之一:

gorm.Open 的 automatic ping(gorm.go:204,!DisableAutomaticPing 且 ConnPool
为 *sql.DB 时调 pinger.Ping() 无超时)在 pingWithTimeout 之前就无限阻塞。
挂起 DB 下 initDB 的 gorm.Open 永久 hang,根本到不了 pingWithTimeout。
修复:initDB/InitDBWithReplicas 的 gormConfig 加 DisableAutomaticPing: true,
框架用 pingWithTimeout(3s)自管启动 ping。

行为闭环测试(3 缺口补齐):
- manager_hdb1_internal_test.go:新增 TestInitDBBoundsHungDB_Hdb1 /
  TestInitDBWithReplicasBoundsHungDB_Hdb1(hungDialector 注入挂起 *sql.DB,
  回归启动 master/replica ping 路径有界)。原 3 用例保留。
- redis_hdb1_internal_test.go:startHungRedisListener(accept 不响应模拟挂起
  Redis)+ TestRedisHealthCheckBoundsHungRedis_Hdb1,行为验证 HealthCheck
  受 client ReadTimeout 3s 约束(不再是推断)。提取 newRedisClient helper
  供 Init 与测试共用。
- app_hdb1_test.go:TestAppInitHungDBBounded_Hdb1 App 级端到端--App.Init
  挂起 DB 有界失败(~30s 5 次重试,非无限 hang)+ Shutdown 正常退出。

验证:database -race -short green(24.7s,6 个 H-db-1 用例)、root 包 App
-race green(33.5s,含端到端)、build/vet 干净。CHANGELOG 更新。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 00:52:17 +08:00
杭州明婳科技 5eb3879a85 fix(database): H-db-1 ping 路径统一经 pingWithTimeout 3s 约束(M11 完整覆盖)
module 04 database 评审发现 H-db-1(HIGH):M11 的 pingWithTimeout 只加到包级
HealthCheck(),未覆盖 4 条 ping 路径:
- (*Manager).HealthCheck(被后台探活 probeOnce master + /health 端点共用)
- probeOnce 从库 ping
- InitDB 启动 master ping
- InitDBWithReplicas 启动 replica ping

挂起 DB(连接活但不响应,区别于宕机的 connection-refused 快速失败)下,这些
路径的 sqlDB.PingContext(ctx) 用 rootCtx/Background(无 deadline)无限阻塞,
致:探活 goroutine 阻塞至 shutdown、#21 自愈冻结(replicaHealthy 停留旧值、
Replica() 可能路由到已死从库)、IsHealthy() 缓存失真、App.Init 启动卡死。

修复:4 路径统一改用 pingWithTimeout(sqlDB, ctx),受 healthCheckTimeout(3s)
约束(context.WithTimeout 尊重 ctx 自带更短 deadline)。/health 端点随之收紧
到 3s(更快失败,非回归);InitDB 5 次重试给足 15s+ 余量无误判。

回归测试 manager_hdb1_internal_test.go:注册 hungDriver(Conn.Ping 阻塞到 ctx
取消模拟挂起 DB),验证 pingWithTimeout / m.HealthCheck / probeOnce replica 三
路径在 Background ctx 下 ~3s 返回(修复前无限 hang)。go test -race ./database/
绿(含 3 条 ~3s 挂起用例)。

对抗复核(diff scan):4 路径均 pingWithTimeout,defer cancel 无 ctx 泄漏,
无新缺陷。CHANGELOG 记录。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 19:14:04 +08:00