2015-08-23 11 views
6

Nie mogę dowiedzieć się, jak zadzwonić pod numer cloud.WithContext i google.DefaultClient, jeśli mam appengine.Context, a nie context.Context.Jak utworzyć kontekst chmury.Context from appengine.Context

Istnieją (stare) pakiety "appengine" i (nowe) "google.golang.org/appengine". Pierwszy z nich przynosi zwyczaj appengine.Context gdy drugi z nich wyposażony context.Context z "golang.org/x/net/context"

Cały google.golang.org/cloud oczekuje tylko context.Context.

Byłbym szczęśliwy mogąc przejść do korzystania z nowego "google.golang.org/appengine", ale utknąłem z runtime.RunInBackground, które nie zostały jeszcze przeniesione. Od https://github.com/golang/appengine:

appengine/aetest, appengine/cloudsql i appengine/runtime nie zostały jeszcze przeniesione.

Co mogę napisać, jeśli appengine/runtime zostały już przeniesione:

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) 
     … 
    }) 
} 

ale nie ma jeszcze "google.golang.org/appengine/runtime". Więc mam

runtime.RunInBackground(c, func(ctx appengine.Context) { 
+0

Jeśli zrobię lewę z 'oauth2.NoContext', pojawia się błąd" nie jest kontekstem App Engine " –

+0

Istnieje funkcja' BackgroundContext() context.Context' ale przeznaczona jest dla zarządzanego vm tylko https: // github. com/golang/appengine/blob/master/appengine_vm.go # L30 Wygląda na to, że powinienem używać zarządzanej maszyny wirtualnej do mojego zadania –

Odpowiedz

2

W tej chwili nie ma sposobu na uzyskanie chmury context.Context z (starej) appengine.Context.

rozwiązanie dla Zarządzane VM

Miesiąc temu BackgroundContext() metoda was added do google.golang.org/appengine (dostępny tylko dla VM Zarządzane). Pozwala to uruchomić goroutine i uzyskać chmurę context.Context bez jej przekazywania.

rozwiązanie dla klasycznych AppEngine

Nie ma rozwiązania w tej chwili.

2

Wykonaj:

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) 
} 

Lub jeśli przechodzącej poświadczeń przez serwer dev nie działa, można również korzystać z jawnych poświadczeń:

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 
} 
+0

Problem polega na tym, że chcę wykonać pracę w tle i nie mogę przekazywać kontekstu.Context przez runtime.RunInBackground (c , func (ctx appengine.Context) call. To tylko appengine.Context może przejść ponad –

+0

Czy możesz użyć pakietu opóźnienia? https://cloud.google.com/appengine/docs/go/taskqueue/delay.Nowsze biblioteki mają kontekst.Context: http://godoc.org/google.golang.org/appengine/delay – Caleb

+0

Nie, muszę uruchomić goroutine na tym samym wystąpieniu. Powinno wypróżnić buforowane dane do Cloud Storage –

1

Oto jak możesz robić, co chcesz:

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) 
} 

Możesz pobrać bibliotekę goauth2 z https://code.google.com/p/goauth2/source/browse/

+0

1) Przepraszamy, ale kod.google.com jest nieaktualny jako całość, a w szczególności kod.google.com/p/goauth2 (mówi się, że używa https://github.com/golang/oauth2, które nie mają pojęcia o "appengine") –

+0

2) Niestety, twoja druga opcja "nie jest kontekstem App Engine" przy próbie zapisu do Cloud Storage –

+0

1) Tak, jest przestarzała, ale czy działa? Możesz znaleźć bibliotekę na https://code.google.com/p/goauth2/source/browse/ –