context.WithValue功能比较强大,它可以携带任意类型的值,下面我们以一个例子来看一下如何通过context添加、获取数据。 packagemainimport("context""fmt")funcAddValue(ctx context.Context)context.Context {returncontext.WithValue(ctx,"keyGuan","this is the value") }funcGetValue(ctx context.Context, keystring)...
func step1(ctx context.Context) context.Context { //根据父context创建子context,创建context时允许设置一个<key,value>对,key和value可以是任意数据类型 child := context.WithValue(ctx, "name", "大脸猫") return child } func step2(ctx context.Context) context.Context { fmt.Printf("name %s\n", c...
packagemainimport("context""fmt""google.golang.org/grpc/metadata")// 使用context.WithValue()和Value()方法获取值funcGetContextValue(){typekey =struct{} ctx := context.Background() ctx = context.WithValue(ctx, key{},"this is value") fmt.Printf("value: %v\n", ctx.Value(key{})) }//...
并发读写这些 value 可能会造成数据错乱,严重的情况下可能发生 panic,所以在并发时,如果我们的业务代码需要读写 context 中的 value,那么最好建议我们 clone 一份原来的 context 中的 value,并塞到新的 ctx 传递给各个gorouinte。
Context链式传递 避免存储和全局变量 使用WithContext函数 及时取消 利用Value携带必要元数据 尊重Context的取消 适当设置Timeout和Deadline 1. 将Context作为第一个函数参数 最佳实践: funcDoSomething(ctx context.Context,arg1 Type1,arg2 Type2){// ...} ...
这里内部实际用到了 context.Value() 方法 // 各种处理,无关代码删除了 // 处理请求 for { // 检查是否关闭了,如果关闭了就直接返回 select { case <-ctx.Done(): req.closeBody() return nil, ctx.Err() default: } // 发送请求出去 }}来总结下上面这段代码,实际上关于 context ...
Context 包是一个轻量级的工具,它提供了一个标准的接口,用于在 goroutine 之间传递请求范围的数据、取消信号和截止时间。Context 包实现了一种类似于树状结构的数据结构,其中每个节点都表示一个请求范围。每个节点都有一个唯一的 key-value 对,其中...
context 主要用来在 goroutine 之间传递上下文信息,包括:取消信号、超时时间、截止时间、k-v 等。 context 用来解决 goroutine 之间退出通知、元数据传递的功能。 控制并发有两种经典的方式,一种是WaitGroup,另外一种就是Context Value函数并没有任何保证,编译器不会检查传进来的参数是否是合理。
) interface{} { // 获取traceid,在调用rpc时记录日志 traceId, _ := ctx.Value(TraceIdKey) // 发起请求 // return} 接收到请求后,通过req获取到traceId并记录到Context中,在调用其他RPC服务和查询DB时,传入构造的Context。在后续代码中,可以通过Context拿到存入的traceId。
在context包中定义有emptyCtx、cancelCtx、timerCtx、valueCtx 四种结构体。其中cancelCtx、timerCtx实现了给子协程传递取消信号。valueCtx结构体实现了父协程和子协程传递共享数据相关。本节我们重点来看跟传递信号相关的Context。 在上面示例中,我们通过context.WithTimeout函数创建了一个带定时取消功能的Context实例,该示...