gpt4 book ai didi

google-app-engine - 如何在 Google App Engine 标准环境中使用 Gorilla session 避免内存泄漏?

转载 作者:IT王子 更新时间:2023-10-29 01:38:21 25 4
gpt4 key购买 nike

我正在使用 Gorilla 在 Google App Engine 上启用 session 变量。到目前为止,我只导入了“github.com/gorilla/sessions”,但是 Gorilla 的页面显示:

If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory! An easy way to do this is to wrap the top-level mux when calling http.ListenAndServe:

http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux))

我的问题是如何针对 App Engine 标准环境调整它,据我所知默认情况下不使用 http.ListenAndServe。我的代码如下所示:

package test

import (
"fmt"
"net/http"
"github.com/gorilla/sessions"
)

func init() {
http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {

var cookiestore = sessions.NewCookieStore([]byte("somesecret"))
session, _ := cookiestore.Get(r, "session")
session.Values["foo"] = "bar"

fmt.Fprintf(w, "session value is %v", session.Values["foo"])

}

这样会导致内存泄漏吗?

最佳答案

您引用的文档告诉了您需要做的一切:使用 context.ClearHandler() 包装您的处理程序.因为你“只”有一个处理程序函数而不是一个http.Handler , 你可以使用 http.HandlerFunc适配器获取实现 http.Handler 的值:

func init() {
http.Handle("/", context.ClearHandler(http.HandlerFunc(handler)))
}

您需要为注册的每个处理程序执行此操作。这就是为什么文档提到将传递给 http.ListenAndServe() 的根处理程序包装起来更容易。 (这样你就不必包装其他非顶级处理程序)。但这不是唯一的方法,只是最简单/最短的方法。

如果您自己不调用 http.ListenAndServe()(如在 App Engine 中),或者您没有单个根处理程序,那么您需要手动包装所有处理程序注册。

请注意 context.ClearHandler() 返回的处理程序没有任何神奇之处,它所做的只是调用 context.Clear()在调用你传递的处理程序之后。因此,您可以在处理程序中轻松调用 context.Clear() 来实现相同的效果。

如果你这样做,一件重要的事情是使用 defer 就好像由于某种原因 context.Clear() 不会到达(例如前面的 return 语句),你会再次泄漏内存。即使您的函数发生 panic ,也会调用延迟函数。所以应该这样做:

func handler(w http.ResponseWriter, r *http.Request) {
defer context.Clear(r)

var cookiestore = sessions.NewCookieStore([]byte("somesecret"))
session, _ := cookiestore.Get(r, "session")
session.Values["foo"] = "bar"

fmt.Fprintf(w, "session value is %v", session.Values["foo"])
}

另请注意, session 存储的创建只能进行一次,因此请将其从您的处理程序中移出到全局变量中。并检查和处理错误,以免您头疼。所以最终建议的代码是这样的:

package test

import (
"fmt"
"net/http"
"log"

"github.com/gorilla/context"
"github.com/gorilla/sessions"
)

func init() {
http.Handle("/", context.ClearHandler(http.HandlerFunc(handler)))
}

var cookiestore = sessions.NewCookieStore([]byte("somesecret"))

func handler(w http.ResponseWriter, r *http.Request) {
session, err := cookiestore.Get(r, "session")
if err != nil {
// Handle error:
log.Printf("Error getting session: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session.Values["foo"] = "bar"

fmt.Fprintf(w, "session value is %v", session.Values["foo"])
}

关于google-app-engine - 如何在 Google App Engine 标准环境中使用 Gorilla session 避免内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48199178/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com