提案:使 exec
遵循使用 Context
对象的指南
作者(s):凯西·巴克
最后更新时间:2018-07-17
摘要
本提案旨在向 exec
包中添加 cmd.StartCtx()
和 cmd.RunCtx()
方法,最终弃用 exec.CommandContext()
,并使其符合 Context
对象使用的指南。
背景
context
包的文档表示:
不要将 Context 存储在结构体类型中;相反,应将 Context 显式传递给需要它的每个函数。Context 应作为第一个参数,通常命名为 ctx。exec.CommandContext()
函数违反了这一规则;它将 ctx
参数存储在 Cmd
对象中,直到稍后由 cmd.Start()
方法引用(该方法也由 cmd.Run()
调用)。cmd.Start()
或 cmd.Run()
的调用者无法控制在执行过程中使用哪个上下文。
最初在这里提出的问题:
https://groups.google.com/forum/#!topic/golang-nuts/uvJIogNTD2c
查看 exec
包对 context,
的使用的开发历史,我怀疑这种不一致性是意外发生的,因为早期开发中 Cmd.ctx
字段被用于不同的方式。
建议
- 在
exec
包中添加以下两个新方法:func (c *Cmd) StartCtx(ctx context.Context) error
func (c *Cmd) RunCtx(ctx context.Context) error
这两个方法尊重传入的上下文,而不是可能附加到Cmd
的任何上下文。 - 在
exec
包中弃用以下函数:func CommandContext(ctx context.Context, name string, arg ...string) *Cmd
一旦弃用完成,可以从Cmd
对象中删除私有的ctx
字段。
理由
context
包的建议是可靠的;应在启动长时间运行的操作时传递上下文对象。这使得可以清楚地看出哪些调用是长时间运行的,并且允许源对象(在这种情况下是 Cmd
)在创建时无需了解最终可能用于控制执行的 ctx
。
兼容性
第 1 部分(添加两个新方法)不会破坏兼容性,尽管它引入了一些可能的混淆,即如果最初使用 exec.CommandContext()
为创建 Cmd
对象,则新方法将忽略提供的上下文。
第 2 部分(弃用 exec.CommandContext()
函数)是一个硬性的兼容性破坏。
实现
待定。这是我的第一个建议,我还不太熟悉 Go 发布过程,但如果这个建议被接受,我很愿意提供补丁。
4条答案
按热度按时间olqngx591#
正如您所说,添加这些方法可能会导致与CommandContext的混淆。我可能最好等待Go2版本,届时CommandContext可以被移除,
Run
和Start
.changed的签名可以接受一个context.Context类型的参数。这不应该是一个指向context.Context的指针。
7gs2gvoe2#
你是否考虑将此提议作为Go2清理的一部分?目前看来,添加功能和弃用其他功能似乎没有任何重大优势。
mnemlml83#
感谢@bontibon。我已经修复了调用签名。
我同意,Go2是这个的最佳目标。对于提议Go2更改有不同的过程吗?(尽管新的这些方法不会破坏兼容性,它们可能在过渡的Go 1.x版本中是可以接受的。)
envsm3lx4#
此外,名称应为
RunContext
和StartContext
,以匹配stdlib中其他地方使用的函数名,用于上下文集成。