Overview
服务每接受到一个request应该生成一个context并且对服务的外部调用应该接受context。服务之间的方法链调用必须传递context,选择性的替换为不同派生的context,当一个context被cancel时,所有从他派生的context都会被cancel。
withCancel,WithDealine,WithTimeout方法持有一个parentContext并且返回一个派生context与一个CancalFunc。调用CancelFunc会cancel该子context与其孩子context,移除父context对该子context的引用,停止任何关联的timer。调用CancelFunc失败会泄露子context及其孩子context直到父context被cancel或者触发timer。go vet(审查) tool会检查CancelFuncs是否被用在所有控制流路径上。
使用context的程序应该遵从以下规则以保持包之间的接口一致性和使静态分析工具可以检查context传播
- 不要存储context在结构类型中,相反将context显式地传递给每个需要它的function中,context应该放在第一参数,命名为ctx
func DoSomething(ctx context.Context, arg Arg) error {
// ... use ctx ...
}
2.不要传递空context,甚至function允许这样子。传递context.TODO如果你不确定需要使用哪个Context
3.仅对传输进程和API的请求范围数据使用上下文值,而不是将可选参数传递给函数。
4.相同的context可能会被传递进不同协程调用的方法,context能够安全的同时被多个携程使用。
Variables
Canceled是错误会返回context canceled当context被cancel
DeadlineExceeded 是错误类型,当context的过时
func WithCancel
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
withcancel返回一个parent的复制包含一个新的Done channel。返回的Done Channel会在调用返回的cancel函数,或者在父context的Done channel关闭时关闭,谁先发生都会触发。
取消此上下文将释放与其关联的资源,因此在该上下文中运行的操作完成后,代码应立即调用cancel。
func WithDeadline
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
WithDealline 返回parent context的复制包含deadline调整为不晚于d,如果父context的deadline已经早于d,WithDeadline(parent, d)语义等同于父对象。返回的context的done channel会在超过deadline与cancelFunc被调用时关闭,或者父context的done channel关闭了,谁先发生都会触发。
取消此上下文将释放与其关联的资源,因此在该上下文中运行的操作完成后,代码应立即调用cancel。
func WithTimeout
返回WithDeadline(parent, time.Now().Add(timeout)).
type CancelFunc
CancelFunc通知操作系统放弃它的任务,这个CancelFunc不会等待任务完成才结束,并发调用该方法时只有第一个会真正执行。
type Context
Context会持有dealine,cancellation信号与其他需要跨越api界限的值。
context方法可能会被多个协程同时调用。
结构体注释太多了,自己找sdk里面看,有个done chan需要看看
func Background
Background返回非空context。它永远不会被取消,没有值,也没有截止日期。它通常由主函数、初始化和测试使用,并作为传入请求的顶级context。
func TODO
TODO返回一个非零的空上下文。代码应该使用上下文.TODO当不清楚要使用哪个上下文或者它还不可用时(因为周围的函数还没有被扩展以接受上下文参数)。
fuanc WithValue
func WithValue(parent Context, key, val interface{}) Context
WithValue返回与value关联的key为val的parentContext的复制。
提供的键必须是可比较的,并且不应是string类型或任何其他内置类型,以避免使用context的包之间发生冲突。WithValue的用户应该为键定义自己的类型。为了避免在分配给接口{}时进行分配,上下文键通常具有具体的struct{}类型。或者,导出的上下文键变量的静态类型应该是指针或接口。
有疑问加站长微信联系(非本文作者)