Skip to content

🐯 [资源] StartLogger 泄漏 goroutine(ctx 不取消时永久驻留) · metrics.go #137

Description

@github-actions

来自 #136 的架构级评审建议。不阻塞合入,仅供参考是否有更好的架构解法。

💡 [建议 · 资源] StartLogger 泄漏 goroutine(ctx 不取消时永久驻留) pkg/metrics/metrics.go

问题根因StartLogger 接收 context.Context 但两个 Server main 都传入了 context.Background()——一个永不取消的 context。后台 goroutine 将随进程生命周期永久驻留,进程退出时自然终止。严格来说这并非 bug(进程退出时 OS 回收一切),但会阻碍 goroutine 泄漏检测(如 runtime.NumGoroutine 监控在正常操作中不会看到此计数回落;若 future 有测试或优雅关闭流程,该 goroutine 也会泄漏)。

为什么低级解法不够:简单地给 StartLogger 加一行 defer 没有意义,因为 main 函数不会 return。问题不是「忘记 defer cancel」,而是 API 签名暗示了可取消性但实际调用方从不取消——这是一种契约误导。

架构级方案:方案一(最小改动):在导出函数上明确契约——改成 StartLogger(interval) 不带 ctx,或签名改为 StartLogger(stop <-chan struct{}),消除「可取消」的假承诺。方案二(长远):让 metrics 包持有自己的关闭信号,由 Server 的 Shutdown 路径触发(如 metrics.Stop()),纳入进程生命周期管理。这样既保留未来优雅关闭的可能性,又不让调用方误以为传 Background() 是正确用法。

代价/收益:方案一只改签名,无运行时成本;方案二需 Server 持有一个关闭信号。收益:goroutine 生命周期可管理,泄漏检测不误报,测试可干净退出。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions