上下文指在 API 之间或者方法调用之间, 所传递的除业务参数之外的额外信息. 如, 服务端接收客户端的 HTTP 请求之后, 可以把客户端的 IP 地址和端口号, 客户端的身份信息, 请求接收的时间, Trace ID 等放入上下文中, 这个上下文可以在后端的方法调用传递, 后端的业务除了利用正常的参数做一些业务处理, 也可以通过上下文中读取消息请求的时间, Trace ID 等信息做一些其他业务
Go 标准库中的 Context 除了传递上下文, 还提供了其他应用场景, 非常适合并发编程任务的编排, goroutine 的控制
cotext 包定义了 Context 接口, Cotext 的具体实现包括4个方法, 分别是 Deadline, Done, Err 和 Value
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key any) any
}
Deadline 方法返回这个 Context 被完成(done)的截止时间. 如果没有设置截止时间, 则 ok 的值是 false. 连续调用这个对象的 Deadline 将返回相同的结果
Done 方法返回一个 channel 对象. 在 Context 被撤销时, 此 channel 会被关闭(close); 如果 Context 没有被撤销, Done 方法可能返回 nil. 后面的 Done 调用总是返回相同的结果. 当 Done 被关闭时(严格来说, 是 Done 返回的 channel 被关闭时), 可以通过 ctx.Err 获取错误信息. 可能是由 cancel, timeout, deadline 导致 Done 被关闭.
Value 方法返回此 Context 中与指定的 key 相关联的 value
Context 中实现了两个常用的生成顶层 Context 的方法
不知道采取 Background 或者 TODO, 可以直接使用 context.Background
var (
background = new(emptyCtx)
todo = new(emptyCtx)
)
func Background() Context {
return background
}
func TODO() Context {
return todo
}
Err 方法返回使用 Context 时是否正常返回的信息. 如果 Done 没有被关闭, 那么 Err 将返回 nil; 否则, 返回一个非 nil 的 error, 说明被关闭的原因
如果 Err 返回一个非 nil 的 error, 那么后面对 Err 的调用都将返回相同的 error