【问题标题】:How can I create cloud context.Context from appengine.Context如何从 appengine.Context 创建云 context.Context
【发布时间】:2015-11-16 19:25:45
【问题描述】:

如果我有appengine.Context 而不是context.Context,我不知道如何调用cloud.WithContextgoogle.DefaultClient

有(旧)“appengine”和(新)“google.golang.org/appengine”包。第一个带有自定义appengine.Context,而第二个带有来自"golang.org/x/net/context"context.Context

整个google.golang.org/cloud 只需要context.Context

我很乐意改用新的"google.golang.org/appengine",但我坚持使用尚未移植的runtime.RunInBackground。来自https://github.com/golang/appengine

appengine/aetestappengine/cloudsqlappengine/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) {

【问题讨论】:

  • 如果我使用 oauth2.NoContext 耍花招,我会收到错误消息“不是 App Engine 上下文”
  • 有函数 BackgroundContext() context.Context 但它仅适用于托管虚拟机 github.com/golang/appengine/blob/master/appengine_vm.go#L30 看来我应该使用托管虚拟机来完成我的任务

标签: google-app-engine go google-cloud-platform


【解决方案1】:

目前无法从(旧)appengine.Context 获取云context.Context

托管虚拟机解决方案

一个月前 BackgroundContext() 方法 was addedgoogle.golang.org/appengine(仅适用于托管 VM)。这允许启动 goroutine 并获取云 context.Context 而无需将其传入。

经典 Appengine 解决方案

暂时没有解决办法。

【讨论】:

    【解决方案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
    }
    

    【讨论】:

    【解决方案3】:

    这里是你可以做你想做的事:

    import (
        "code.google.com/p/goauth2/appengine/serviceaccount"
        "golang.org/x/net/context"
        "appengine"
    )
    
    // oauth2 module requires a context.Context so use goauth2 for now
    func CloudContext(c appengine.Context, scopes ...string) context.Context {
        client, _ := serviceaccount.NewClient(c, scopes...)
        return cloud.WithContext(context.Background(), appengine.AppID(c), client)
    }
    

    你可以从https://code.google.com/p/goauth2/source/browse/获取goauth2库

    【讨论】:

    • 1) 抱歉,code.google.com 已被整体弃用,尤其是 code.google.com/p/goauth2(据说使用 github.com/golang/oauth2 对“appengine”一无所知")
    • 2) 抱歉,您的第二个选项在尝试写入 Cloud Storage 时得到“不是 App Engine 上下文”
    • 1) 是的,它已被弃用,但它有效吗?您可以在code.google.com/p/goauth2/source/browse 找到图书馆
    • 弃用的代码是否有效并不重要。我不会在新项目中使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    • 2013-05-14
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    相关资源
    最近更新 更多