AppEngine:使用与请求无关的上下文

huangapple go评论94阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2017年5月4日 00:02:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/43765014.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定