Chromium Code Reviews| Index: appengine/gaemiddleware/context.go |
| diff --git a/appengine/gaemiddleware/context.go b/appengine/gaemiddleware/context.go |
| index 31481d5b6877e0a7321ce3b23eb66e173319dbba..916fac17b7b54a72b28d5a380ff5fa920c555604 100644 |
| --- a/appengine/gaemiddleware/context.go |
| +++ b/appengine/gaemiddleware/context.go |
| @@ -6,11 +6,13 @@ package gaemiddleware |
| import ( |
| "net/http" |
| + "os" |
| "golang.org/x/net/context" |
| "google.golang.org/appengine" |
| "github.com/luci/gae/filter/dscache" |
| + "github.com/luci/gae/impl/cloud" |
| "github.com/luci/gae/impl/prod" |
| "github.com/luci/gae/service/urlfetch" |
| @@ -31,6 +33,8 @@ import ( |
| "github.com/luci/luci-go/appengine/gaesettings" |
| "github.com/luci/luci-go/appengine/tsmon" |
| "github.com/luci/luci-go/luci_config/appengine/gaeconfig" |
| + |
| + "cloud.google.com/go/datastore" |
| ) |
| var ( |
| @@ -66,6 +70,31 @@ var ( |
| globalTsMonState = &tsmon.State{} |
| ) |
| +// WithCloud installs the set of standard flexible environment services. |
| +// Notably, this does not install Memcache (not available in Flex) or use DS cache |
| +// (requires memcache). |
| +func WithCloud(c context.Context) context.Context { |
| + c = logging.SetLevel(c, logging.Debug) |
| + project := os.Getenv("GCLOUD_PROJECT") |
|
hinoka
2017/04/17 23:31:17
This assumes we are in a GCE container.
|
| + // Use the cloud datastore client. |
| + dsClient, err := datastore.NewClient(c, project) |
| + if err != nil { |
| + panic(err) |
| + } |
| + c = cloud.Config{DS: dsClient}.Use(c) |
| + c = settings.Use(c, globalSettings) |
| + |
| + // The rest of the service may use applied configuration. |
| + c = proccache.Use(c, globalProcessCache) |
| + c = gaeconfig.Use(c) |
| + c = gaesecrets.Use(c, nil) |
| + c = auth.SetConfig(c, globalAuthConfig) |
| + |
| + // Wrap this in a cache context so that lookups for any of the aforementioned |
| + // items are fast. |
| + return cacheContext.Wrap(c) |
| +} |
| + |
| // WithProd adds various production GAE LUCI services to the context. |
| // |
| // Basically, it installs GAE-specific backends and caches for various |
| @@ -132,3 +161,29 @@ func prodServices(c *router.Context, next router.Handler) { |
| next(c) |
| } |
| + |
| +// CloudServices is a middleware that installs the set of standard production |
| +// AppEngine services by calling WithCloud. |
| +func CloudServices(c *router.Context, next router.Handler) { |
| + // Create a cancelable Context that cancels when this request finishes. |
| + // |
| + // We do this because Contexts will leak resources and/or goroutines if they |
| + // have timers or can be canceled, but aren't. Predictably canceling the |
| + // parent will ensure that any such resource leaks are cleaned up. |
| + var cancelFunc context.CancelFunc |
| + c.Context, cancelFunc = context.WithCancel(c.Context) |
| + defer cancelFunc() |
| + |
| + // Apply production settings. |
| + c.Context = WithCloud(c.Context) |
| + |
| + next(c) |
| +} |
| + |
| +// BaseCloud returns a list of middleware: CloudServices middleware, a panic catcher if this |
| +// is not a devserver, and the monitoring middleware. |
| +func BaseCloud() router.MiddlewareChain { |
| + return router.NewMiddlewareChain( |
| + CloudServices, middleware.WithPanicCatcher, globalTsMonState.Middleware, |
| + ) |
| +} |