golang goroutine 通知_Golang 如何正确使用 Context - Go语言中文社区

golang goroutine 通知_Golang 如何正确使用 Context


27e07925e4fe0a17d92b735d0588a016.png

视频信息

How to correctly use package context

by Jack Lindamood

at Golang UK Conf. 2017

视频:https://www.youtube.com/watch?v=-_B5uQ4UGi0

博文:https://medium.com/@cep21/how-to-correctly-use-context-context-in-go-1-7-8f2c0fafdf39

为什么需要 Context

  • 每一个长请求都应该有个超时限制
  • 需要在调用中传递这个超时
  • 比如开始处理请求的时候我们说是 3 秒钟超时
  • 那么在函数调用中间,这个超时还剩多少时间了?
  • 需要在什么地方存储这个信息,这样请求处理中间可以停止

如果进一步考虑。

51241f0a015159621506a17c6a556359.png

如上图这样的 RPC 调用,开始调用 RPC 1 后,里面分别调用了 RPC 2, RPC 3, RPC 4,等所有 RPC 用成功后,返回结果。

这是正常的方式,但是如果 RPC 2 调用失败了会发生什么?

991ad332d04ae9a7c0b00c79b07ec423.png

RPC 2 失败后,如果没有 Context 的存在,那么我们可能依旧会等所有的 RPC 执行完毕,但是由于 RPC 2 败了,所以其实其它的 RPC 结果意义不大了,我们依旧需要给用户返回错误。因此我们白白的浪费了 10ms,完全没必要去等待其它 RPC 执行完毕。

那如果我们在 RPC 2 失败后,就直接给用户返回失败呢?

99b47acc411b1935953b4afc7304faf4.png

用户是在 30ms 的位置收到了错误消息,可是 RPC 3 和 RPC 4 依然在没意义的运行,还在浪费计算和IO资源。

7fdb51374edb64248026240624492df4.png

所以理想状态应该是如上图,当 RPC 2 出错后,除了返回用户错误信息外,我们也应该有某种方式可以通知 RPC 3 和 RPC 4,让他们也停止运行,不再浪费资源。

所以解决方案就是:

  • 用信号的方式来通知请求该停了
  • 包含一些关于什么时间请求可能会结束的提示(超时)
  • 用 channel 来通知请求结束了

那干脆让我们把变量也扔那吧。

  • 在 Go 中没有线程/go routine 变量
  • 其实挺合理的,因为这样就会让 goroutine 互相产生依赖
  • 非常容易被滥用

Context 实现细节

context.Context:

  • 是不可变的(immutable)树节点
  • Cancel 一个节点,会连带 Cancel 其所有子节点 (从上到下)
  • Context values 是一个节点
  • Value 查找是回溯树的方式 (从下到上)

示例 Context 链

完整代码:https://play.golang.org/p/ddpofBV1QS

package mainfunc tree() { ctx1 := context.Background() ctx2, _ := context.WithCancel(ctx1) ctx3, _ := context.WithTimeout(ctx2, time.Second * 5) ctx4, _ := context.WithTimeout(ctx3, time.Second * 3) ctx5, _ := context.WithTimeout(ctx3, time.Second * 6) ctx6 := context.WithValue(ctx5, "userID
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_39588445/article/details/112099157
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-06-26 20:20:03
  • 阅读 ( 989 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢