我刚刚读了一篇文章:在Go中构建自己的Web框架,为了在处理程序之间共享值,我选择了context.Context,我用以下方式在处理程序和中间件之间共享值:
type appContext struct {
db *sql.DB
ctx context.Context
cancel context.CancelFunc
}
func (c *appContext)authHandler(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request {
defer c.cancel() //this feels weird
authToken := r.Header.Get("Authorization") // this fakes a form
c.ctx = getUser(c.ctx, c.db, authToken) // this also feels weird
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func (c *appContext)adminHandler(w http.ResponseWriter, r *http.Request) {
defer c.cancel()
user := c.ctx.Value(0).(user)
json.NewEncoder(w).Encode(user)
}
func getUser(ctx context.Context, db *sql.DB, token string) context.Context{
//this function mimics a database access
return context.WithValue(ctx, 0, user{Nome:"Default user"})
}
func main() {
db, err := sql.Open("my-driver", "my.db")
if err != nil {
panic(err)
}
ctx, cancel := context.WithCancel(context.Background())
appC := appContext{db, ctx, cancel}
//....
}一切都在工作,处理程序比使用大猩猩/上下文加载得更快,所以我的问题是:
发布于 2015-06-19 05:02:35
您的代码有问题,因为您正在将用户存储到应用程序上下文中。同时有多个用户,它不能工作。上下文必须与不被其他请求覆盖的请求相关。必须将用户存储在请求上下文中。在我的文章中,我使用了以下大猩猩函数:context.Set(r, "user", user)。r是请求。
如果您想在应用程序中使用context.Context,应该使用它们的大猩猩包装器(您可以在本文末尾找到它:https://blog.golang.org/context)。
另外,您不需要使用cancel的上下文。对于根上下文来说,context.Background()是可以的。
发布于 2016-06-17 09:48:09
注意: go 1.7.0-rc2确实澄清了一些如何释放与上下文相关的资源 (萨米尔·阿贾玛尼):
有些用户没有意识到用一个
ContextCancelFunc创建一个会将一个子树附加到父树上,直到调用CancelFunc或取消父树之后才会释放该子树。在包文档的早期就明确这一点,这样学习这个包的人就有了正确的概念模型。
The 现在的文档包括
对服务器的传入请求应该创建一个
Context,而对服务器的传出调用应该接受一个Context。 它们之间的函数调用链必须传播Context,可以选择将其替换为使用WithCancel、WithDeadline、WithTimeout或WithValue创建的派生Context。 这些Context值形成一棵树:当Context被取消时,由此产生的所有Contexts也被取消。WithCancel、WithDeadline和WithTimeout函数返回派生的Context和CancelFunc。 调用CancelFunc将取消新的Context及其派生的任何上下文,从父树中移除Context,并停止任何相关的计时器。 未能调用CancelFunc会泄漏相关资源,直到父Context被取消或计时器触发为止。
发布于 2019-12-23 18:59:38
上下文包的两个主要用例是:
使用上下文可以形成以context.Background()为根的上下文树。WithValue()、context.WithCancel()、WithTimeout()、WithDeadline()是从根上下文派生的上下文,可以进一步划分。每一个例子都可以清楚地说明什么是正确的使用上下文。本指南以适当的例子提供了上述所有内容的使用。
来源:https://golangbyexample.com/using-context-in-golang-complete-guide/
https://stackoverflow.com/questions/30928002
复制相似问题