英文:
AppEngine: using a context not associated with a request
问题
我正在尝试使用PubSub和AppEngine部署API,但是遇到了一个“不是App Engine上下文”的错误,与以下代码相关:
import (
"golang.org/x/net/context"
"log"
"cloud.google.com/go/pubsub"
)
var (
ctx context.Context
pubsubClient *pubsub.Client
)
func InitPubSub() {
ctx = context.Background()
psClient, err := pubsub.NewClient(ctx, "myproject-1234")
if err != nil {
log.Println("(init pub sub) error while creating new pubsub client:", err)
} else {
pubsubClient = psClient
}
}
所以我查看了appengine包中的BackgroundContext函数,但它只适用于AppEngine灵活环境(标准环境似乎更适合我的应用程序):
https://godoc.org/google.golang.org/appengine#BackgroundContext
你知道是否有其他函数可以使用吗?或者我应该为每个请求创建和关闭一个客户端?
谢谢!
英文:
I was trying to deploy an API using PubSub with AppEngine but I got a "not an App Engine context" error, it's related to the following code:
import (
"golang.org/x/net/context"
"log"
"cloud.google.com/go/pubsub"
)
var (
ctx context.Context
pubsubClient *pubsub.Client
)
func InitPubSub () {
ctx = context.Background()
psClient, err := pubsub.NewClient(ctx, "myproject-1234")
if err != nil {
log.Println("(init pub sub) error while creating new pubsub client:", err)
} else {
pubsubClient = psClient
}
}
So I was looking at the BackgroundContext func from the appengine package but it says that it only works with AppEngine flexible environment (standard environment seems more appropriate to my app):
https://godoc.org/google.golang.org/appengine#BackgroundContext
Do you know if there's another function I can use? Or should I create and close a client for each request?
Thanks!
答案1
得分: 1
每个请求都应该创建一个新的客户端(当客户端需要一个context
时)。请求的context
处理取消和超时等事务。因此,如果你的请求被取消,你也应该取消任何外部API请求。客户端处理所有外部API请求,因此它需要相同的context
。
App Engine标准要求请求使用App Engine上下文,因为它会自动处理扩展和资源。
你可以通过调用appengine.NewContext(req)
(g3doc)从请求中获取一个context.Context
。
例如:
import (
"net/http"
"cloud.google.com/go/pubsub"
"google.golang.org/appengine"
"google.golang.org/appengine/log"
)
func pubSubHandler(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
client, err := pubsub.NewClient(ctx, "myproject-1234")
if err != nil {
log.Errorf(ctx, "pubsub.NewClient: %v", err)
http.Error(w, "An error occurred. Try again.", http.StatusInternalServerError)
return
}
_ = client // 使用客户端。
}
另一个注意事项是在App Engine标准中使用google.golang.org/appengine/log
包进行日志记录,如上所示。请参阅读写应用程序日志。
官方文档中的使用Go构建应用程序描述了如何在App Engine标准上构建示例应用程序。
英文:
Each request should create a new client (when the client requires a context
). The context
of the request handles things like cancels and timeouts. So, if your request gets cancelled, you should also cancel any of the outgoing API requests. The client handles all of the outgoing API requests, so it needs the same context
.
The App Engine Standard requires requests to use the App Engine context since it handles scaling and resources automatically.
You can get a context.Context
from a request by calling appengine.NewContext(req)
(g3doc).
For example:
import (
"net/http"
"cloud.google.com/go/pubsub"
"google.golang.org/appengine"
"google.golang.org/appengine/log"
)
func pubSubHandler(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
client, err := pubsub.NewClient(ctx, "myproject-1234")
if err != nil {
log.Errorf(ctx, "pubsub.NewClient: %v", err)
http.Error(w, "An error occurred. Try again.", http.StatusInternalServerError)
return
}
_ = client // Use the client.
}
Another note is to use the google.golang.org/appengine/log
package to do logging in App Engine Standard, as done above. See Reading and Writing Application Logs.
Building an App with Go from the official docs describes how to build an example application on App Engine Standard.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论