如果我有cloud.WithContext
而不是google.DefaultClient
,我无法确定如何拨打appengine.Context
和context.Context
。
有(旧)" appengine"和(新)" google.golang.org/appengine"包。当第二个来自appengine.Context
context.Context
时,第一个会自定义"golang.org/x/net/context"
整个google.golang.org/cloud
只需要context.Context
。
我很乐意转而使用新的"google.golang.org/appengine"
,但我已经坚持使用尚未移植的runtime.RunInBackground
。来自https://github.com/golang/appengine:
appengine/aetest
,appengine/cloudsql
和appengine/runtime
尚未移植。
如果appengine/runtime
已被移植,我可以写什么:
import (
"golang.org/x/net/context"
"google.golang.org/appengine"
"google.golang.org/appengine/runtime"
"google.golang.org/cloud"
"google.golang.org/cloud/storage"
)
func handler(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
runtime.RunInBackground(c, func(ctx context.Context) {
hc, _ := google.DefaultClient(ctx, storage.ScopeFullControl)
cc := cloud.WithContext(ctx, appengine.AppID(ctx), hc)
…
})
}
但还没有"google.golang.org/appengine/runtime"
。所以我有
runtime.RunInBackground(c, func(ctx appengine.Context) {
答案 0 :(得分:2)
这样做:
func getCloudContext(appengineContext context.Context) context.Context {
hc := &http.Client{
Transport: &oauth2.Transport{
Source: google.AppEngineTokenSource(appengineContext, storage.ScopeFullControl),
Base: &urlfetch.Transport{Context: appengineContext},
},
}
return cloud.NewContext(appengine.AppID(appengineContext), hc)
}
或者,如果通过开发服务器传递凭据不起作用,您还可以使用显式凭据:
func getCloudContext(aeCtx context.Context) (context.Context, error) {
data, err := ioutil.ReadFile("/path/to/credentials.json")
if err != nil {
return nil, err
}
conf, err := google.JWTConfigFromJSON(
data,
storage.ScopeFullControl,
)
if err != nil {
return nil, err
}
tokenSource := conf.TokenSource(aeCtx)
hc := &http.Client{
Transport: &oauth2.Transport{
Source: tokenSource,
Base: &urlfetch.Transport{Context: aeCtx},
},
}
return cloud.NewContext(appengine.AppID(aeCtx), hc), nil
}