大家好,我是煎鱼。,在 Go 中有一个很经典的设计:context,这是许多同学初学时必学的标准库。涉及到上下文传递、超时控制等必要项。,甚至在函数体中的第一个参数大多是传 context。写第三方库也必须兼容 context 设置,否则会经常有人提需求让你支持。,我觉得这次的新特性更新虽不复杂,但作用挺大。建议大家学习!,以下是一个快速 Demo:,运行结果:,一切都看起来没什么问题。,但在实际写业务代码和排查问题时,你就会发现一个麻烦的事。在出现上下文超时或到达所设置的截止时间时,ctx.Err 方法可以获得 context deadline exceeded 的错误信息。,但这是远远不够的,你只知道是因为诱发了超时。但不知道是哪里导致的,还得再去根据访问的逻辑,再走一遍脑洞,再进行排查。又或是根据代码堆栈,再去设想,最后复现成功。,又或是查不到。因为这种一般是偶现,很有可能就留给下一代的继承者了~,又更有业务诉求,希望在出现上下文的异常场景时,可以及时执行回调方法。然而这没有太便捷的实现方式。,在即将发布的 Go1.21,针对 Context 的错误处理终于有了一点点的增强,来填补这个地方的信息,允许添加自定义的错误类型和信息。,新增的 Context API 如下:,与原先的 WithDeadline 和 WithTimeout 作用基本一致,唯一区别就是在形参上增加了 cause error,允许传入错误类型。,WithTimeoutCause 的使用示例:,像上述程序,执行 ctx.Err 方法时得到的结果是:context.DeadlineExceeded,这是既有的。,此时,我们再结合在 Go1.20 版本加入的 context.Cause 方法:,就能得到对应的错误信息,上述的结果对应的是 tooSlow 变量。,WithCancelCause 的使用示例,计时器先触发:,对应的程序结果:,先发生上下文取消的使用示例:,对应的程序结果:,同样的,在 Go1.21 也对 Context(上下文)被取消的动作后增加了一些增强。平时当上下文被取消时,我们只能通过启动 Goroutine 来监视取消行为并做一系列操作。,但这未免繁琐且增大了我们的编码和运行成本,因为每次处理都要 goroutine+select+channel 来一套组合拳,才能真正到写自己业务代码的地方。,为此新版本增加了注册函数的功能,将会在上下文被取消时调用。函数签名如下:,在函数作用上,该函数会在 ctx 完成(取消或超时)后调用所传入的函数 f。,在运行机制上,它会自己在 goroutine 中调用 f。需要注意的是,即使 ctx 已经完成,调用 AfterFunc 也不会等待 f 返回。,这也是可以套娃的,在 AfterFunc 里再套 AfterFunc。这里用不好也很容易 goroutine 泄露。,基于这个新函数,可以看看以下两个例子作为使用场景。,1、多 Context 合并取消的例子:,2、在取消上下文时停止等待 sync.Cond:,基本满足了各种上下文的复杂诉求了。,Context 一直是大家使用的最频繁的标准库之一,他联通了整个 Go 里的工程体系。这次在 Go1.21 对 Context 增加了 WithXXXCause 相关函数的错误类型支持。对于我们在 Go 工程实践中的排查和定位,能够有一些不错的助力。,另外 AfterFunc 函数的增加,看起来是个简单的功能。但是可以解决以往的一些合并取消上下文和串联处理的复杂场景,是一个不错的扩展功能。,苛刻些,美中不足的就是,Go 都已经发布 10+ 年了,加的还是有些太晚了。同时针对 Context 也需要有更体系的排查和定位侧的补全了。
文章版权声明
1 原创文章作者:cmcc,如若转载,请注明出处: https://www.52hwl.com/27846.html
2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈
3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)
4 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别