函数 | 作用 |
---|
context.Background() | 创建一个根 Context |
context.TODO() | 作为占位 Context |
context.WithCancel(parent) | 创建可手动取消的 Context |
context.WithTimeout(parent, timeout) | 创建超时自动取消的 Context |
context.WithDeadline(parent, time) | 创建在指定时间点自动取消的 Context |
context.WithValue(parent, key, value) | 在 Context 中存储键值对 |
Done() | 返回一个通道,Context 结束时关闭 | 监听 Context 取消 |
Err() | 获取 Context 取消的原因 | 判断任务是否被取消或超时 |
Value(key any) any | 获取 Context 存储的值 | 传递请求范围内的参数 |
context.Context 主要用于并发任务管理,在不同Goroutine之间传递取消信号和元数据的。
主g把context传递给子g,主g传递取消信号,子g接收。
使用context共享数据
// 使用context在不同goroutine中共享数据
func main() {
ctx := context.Background() //初始化一个context
process(ctx)
ctx = context.WithValue(ctx, "traceId", "5213") //给context添加数据
process(ctx)
}
func process(ctx context.Context) { // 在函数中传递context
traceId, ok := ctx.Value("traceId").(string) // 获取context值
if ok {
fmt.Printf("process over. trace_id=%s\n", traceId)
} else {
fmt.Printf("process over. no trace_id\n")
}
}
// 现实场景中可能是从一个 HTTP 请求中获取到的 Request-ID。
// requestIDKey 用作在 context 中设置和获取请求 ID 的键
// 定义一个特殊的类型可以避免在不同的包之间使用 context 时发生键的冲突
type contextKey string
const requestIDKey contextKey = "requestID"
// WithRequestID 是一个中间件,它将请求ID从请求头中提取出来,
// 然后将这个ID添加到当前请求的context中。
func WithRequestID(next http.Handler) http.Handler {
return http.HandlerFunc(
func(rw http.ResponseWriter, req *http.Request) {
// 从请求头中获取请求ID
reqID := req.Header.Get("X-Request-ID")
// 使用context.WithValue创建一个新的context,
// 其中包含了从请求头中提取出来的请求ID。
// requestIDKey是用作在context中设置和获取请求ID的键。
ctx := context.WithValue(req.Context(), requestIDKey, reqID)
// 使用req.WithContext创建一个新的请求,
// 其context已经包含了请求ID。
req = req.WithContext(ctx)
// 调用下一个处理器(或中间件),
// 并将更新了context的请求传递给它。
next.ServeHTTP(rw, req)
})
}
// 从Context中获取数据
func GetRequestID(ctx context.Context) string {
return ctx.Value(requestIDKey).(string) // 从Context中获取Request-ID
}
// 中间件处理函数
func Handle(rw http.ResponseWriter, req *http.Request) {
reqID := GetRequestID(req.Context()) //从请求中的Context中获取Request-ID
rw.Write([]byte(reqID))
fmt.Println(reqID)
}
func main() {
//type HandlerFunc func(ResponseWriter, *Request) 把func(ResponseWriter, *Request)函数转换成HandlerFunc类型实现了Handler接口
handler := WithRequestID(http.HandlerFunc(Handle))
err := http.ListenAndServe("127.0.0.1:8000", handler)
if err != nil {
fmt.Println("服务器启动失败")
}
}
传递取消信号