首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Golang context.Context传播

Golang context.Context传播
EN

Stack Overflow用户
提问于 2018-03-08 18:51:31
回答 2查看 3.9K关注 0票数 3

我想问一下,我们应该如何在Golang处理上下文传播的问题。

我的应用程序是HTTP服务器。

我会使用上下文作为信息数据的容器(例如请求id,我从请求或进程中解压缩的一些东西)。

其中最愚蠢的优点之一是车辆数据和标签有用的统计和日志记录。例如,能够在每一行日志中添加我所拥有的所有包中的事务id。

我面临的问题如下:

代码语言:javascript
复制
func handleActivityY(w http.ResponseWriter, r *http.Request) {
    info, err := decodeRequest(r)
    ...
    stepOne, err := stepOne(r.Context(), info)
    ...
    stepTwo, err := stepTwo(r.Context(), stepOne)
    ...
}

这个设计的问题在于,上下文是一个不可变的实体(每当我们添加某个内容或设置一个新的超时时,我们就会有一个新的上下文)。

除非在每个函数调用时返回上下文(以及返回值(如果有的话)和错误),否则不能传播上下文。

要使这项工作发挥作用,唯一的办法是:

代码语言:javascript
复制
func handleActivityY(w http.ResponseWriter, r *http.Request) {
    ctx, info, err := decodeRequest(r)
    ...
    ctx, stepOne, err := stepOne(ctx, info)
    ...
    ctx, stepTwo, err := stepTwo(ctx, stepOne)
    ...
}

我已经用context.Context参数污染了包中的几乎所有函数。在我看来,除了其他参数之外,还返回它似乎有些过火了。

难道真的没有其他更优雅的方法来做到这一点吗?

我目前正在使用gin框架,它有自己的上下文,并且是可变的。我不想为此向Gin添加依赖项。

EN

回答 2

Stack Overflow用户

发布于 2018-03-09 07:25:09

在上下文管道的早期,向数据结构添加一个可变指针:

代码语言:javascript
复制
type MyData struct {
    // whatever you need
}

var MyDataKey = /* something */

ctx, cancel := context.WithValue(context.Background(), MyDataKey, &MyData{})

然后,在需要修改数据结构的方法中,只需这样做:

代码语言:javascript
复制
data := ctx.Value(MyDataKey)
data.Foo = /* something */

所有关于并发访问安全的常规规则都适用,因此,如果多个goroutines可以同时读取/设置数据值,则可能需要使用互斥或其他保护机制。

票数 6
EN

Stack Overflow用户

发布于 2018-03-08 19:13:23

难道真的没有其他更优雅的方法来做到这一点吗?

stepOne可以独立于上下文返回自己的数据,并与调用者如何使用其信息隔离(即将其放入数据库/上下文并将其传递给其他函数)

代码语言:javascript
复制
func handleActivityY(w http.ResponseWriter, r *http.Request) {
    ctx, info, err := decodeRequest(r)
    ...
    stepOne, err := stepOne(ctx, info)
    ...
    ctx = context.WithValue(ctx, "someContextStepTwoNeeds", stepOne.Something())
    stepTwo, err := stepTwo(ctx, stepOne)
    ...
}

所传递的IMO数据的作用域应该是极小的上下文信息。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49180425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档