From 8c06b36013a7276fc55ac9c00fe73cf7c7c54e9e Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 29 Jan 2018 10:53:30 +0100 Subject: [PATCH] Don't use context.Background(). AppEngine panics when you use a non-AppEngine context. Instead, we need to load the config at request time. --- app/config.go | 10 ++++++++++ kraftakt.go | 18 ++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/config.go b/app/config.go index f05a9e6..5b2d867 100644 --- a/app/config.go +++ b/app/config.go @@ -2,6 +2,7 @@ package app import ( "context" + "sync" "google.golang.org/appengine/datastore" "google.golang.org/appengine/log" @@ -18,7 +19,16 @@ var Config struct { GoogleClientSecret string } +var mu sync.Mutex + func LoadConfig(ctx context.Context) error { + mu.Lock() + defer mu.Unlock() + + if Config.ProjectNumber != "" { + return nil + } + key := datastore.NewKey(ctx, "Config", "Production", 0, nil) if err := datastore.Get(ctx, key, &Config); err != nil { log.Errorf(ctx, `datastore.Get("Config", "Production") = %v`, err) diff --git a/kraftakt.go b/kraftakt.go index 69815c2..66668a6 100644 --- a/kraftakt.go +++ b/kraftakt.go @@ -28,10 +28,6 @@ func init() { http.HandleFunc("/google/setup", googleSetupHandler) http.Handle("/google/grant", AuthenticatedHandler(googleGrantHandler)) http.Handle("/", AuthenticatedHandler(indexHandler)) - - if err := app.LoadConfig(context.Background()); err != nil { - panic(err) - } } // ContextHandler implements http.Handler @@ -40,6 +36,11 @@ type ContextHandler func(context.Context, http.ResponseWriter, *http.Request) er func (hndl ContextHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) + if err := app.LoadConfig(ctx); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err := hndl(ctx, w, r); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -51,6 +52,11 @@ type AuthenticatedHandler func(context.Context, http.ResponseWriter, *http.Reque func (hndl AuthenticatedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) + if err := app.LoadConfig(ctx); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + gaeUser := user.Current(ctx) if gaeUser == nil { url, err := user.LoginURL(ctx, r.URL.String()) @@ -206,6 +212,10 @@ func fitbitNotifyHandler(ctx context.Context, w http.ResponseWriter, r *http.Req // handleNotifications parses fitbit notifications and requests the individual // activities from Fitbit. It is executed asynchronously via the delay package. func handleNotifications(ctx context.Context, payload []byte) error { + if err := app.LoadConfig(ctx); err != nil { + return err + } + var subscriptions []fitbit.Subscription if err := json.Unmarshal(payload, &subscriptions); err != nil { return err -- 2.11.0