问题
callWithTimeout(dixinternal/provider.go)在独立 goroutine 中执行 provider,超时后调用方直接返回,不会取消正在跑的调用。同时 initializer[p.fn]=true 仅在成功后设置(dixinternal/dix.go),超时失败后后续 Inject/TryInject 会再次执行同一 provider。
默认 ProviderTimeout=15s,因此默认开启。
影响
- 泄漏的 goroutine 持续占用资源
- 有副作用的构造函数(建连、Listen、Migrate 等)可能被执行两次
- 可能与仍在运行的首次调用产生竞态
建议
- 向 provider 传入可取消的
context.Context,或明确文档:超时无法中止已启动的工作
- 超时后将 provider 标记为失败/不可自动重试,直至显式重置
- 补充回归测试:超时后不应二次调用 / 或文档化重试策略
证据
dixinternal/provider.go callWithTimeout
dixinternal/dix.go provider 调用与 initializer 赋值路径
问题
callWithTimeout(dixinternal/provider.go)在独立 goroutine 中执行 provider,超时后调用方直接返回,不会取消正在跑的调用。同时initializer[p.fn]=true仅在成功后设置(dixinternal/dix.go),超时失败后后续Inject/TryInject会再次执行同一 provider。默认
ProviderTimeout=15s,因此默认开启。影响
建议
context.Context,或明确文档:超时无法中止已启动的工作证据
dixinternal/provider.gocallWithTimeoutdixinternal/dix.goprovider 调用与initializer赋值路径