共计 1104 个字符,预计需要花费 3 分钟才能阅读完成。
概述
golang 似乎为了保证线程安全,context 不允许修改,只能继承,但这样带来的问题就是上文环境无法获取在下文中更新的 context。
func left(ctx context.Context) {right(ctx)
value := GetContextValue(ctx, "key")
fmt.Println(value)
}
func right(ctx context.Context) {ctx := context.WithValue(ctx, "key", "value")
}
因为 right 中 context 并没有改变旧的 ctx,因此 left 中无法获取到 key
的值。
初步想法
我的想法是 ctx 里面塞一个指针,不知道这样是否合理。
// 类似这样,可能不是很准确
func right(ctx context.Context) {sctx := ctx.Value("context").(*SyncContext)
sctx.Set(...)
}
func left(ctx context.Context) {sctx := ctx.Value("context").(*SyncContext)
right(ctx)
fmt.Println(sctx.Get(...))
}
type SyncContext struct {values sync.Map}
func NewSyncContext() *SyncContext { ...}
func (c *SyncContext) Get(key string) any {...}
func (c *SyncContext) Set(key string, value any) {...}
func main() {ctx := context.WithValue(context.Background(), "context", NewSyncContext())
left(ctx)
}
但感觉这种姿势怪怪的。有没有其他的想法?
场景
大概描述一下我的具体场景,http middleware 使用链式调用,第一个中间件是日志中间件,会在所有 next 调用结束后输出日志,请求、响应这些目前都有办法获取了,就是 next 中间件往 req.Context()
写的数据读不到(因为 req.WithContext
也会创建新的 request,而不是修改 request 的 ctx,目前看到的代码也没有提供修改 request context 的途径)。
主要是 next 中间件会进行一些身份认证,会把用户信息写进 context,需要日志最后打出这些用户信息
(PS:因为这些日志是需要以特定格式输出用于审计的,所以各个中间件自行输出可能会比较难受,主要是想各司其职,不要把心智负担下放到下游中间件)。
正文完