Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The LUCI Authors. All rights reserved. | 1 // Copyright 2017 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package config | 5 package config |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "time" | 8 "time" |
| 9 | 9 |
| 10 "github.com/luci/luci-go/appengine/datastorecache" | |
| 11 log "github.com/luci/luci-go/common/logging" | |
| 12 "github.com/luci/luci-go/common/sync/mutexpool" | |
| 13 "github.com/luci/luci-go/luci_config/appengine/backend/datastore" | |
| 14 "github.com/luci/luci-go/luci_config/appengine/gaeconfig" | |
| 10 "github.com/luci/luci-go/luci_config/server/cfgclient/backend" | 15 "github.com/luci/luci-go/luci_config/server/cfgclient/backend" |
| 11 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/caching" | 16 "github.com/luci/luci-go/luci_config/server/cfgclient/backend/caching" |
| 12 | 17 |
| 13 "golang.org/x/net/context" | 18 "golang.org/x/net/context" |
| 14 ) | 19 ) |
| 15 | 20 |
| 16 // CacheOptions is the set of configuration options. | 21 // CacheOptions is the set of configuration options. |
| 17 type CacheOptions struct { | 22 type CacheOptions struct { |
| 18 // CacheExpiration is the amount of time that a config entry should be c ached. | 23 // CacheExpiration is the amount of time that a config entry should be c ached. |
| 19 CacheExpiration time.Duration | 24 CacheExpiration time.Duration |
| 25 | |
| 26 // DatastoreCacheAvailable, if true, indicates that requisite services f or | |
| 27 // datastore cache access are installed in the Context. This requires: | |
| 28 // - A luci/gae datastore service instnace | |
| 29 // - A settings service instance, presumably gaesettings. | |
| 30 DatastoreCacheAvailable bool | |
| 20 } | 31 } |
| 21 | 32 |
| 22 // WrapBackend wraps the supplied backend with caching as appropriately | 33 // WrapBackend wraps the supplied backend with caching as appropriately |
| 23 // configured. | 34 // configured. |
| 24 func (o *CacheOptions) WrapBackend(c context.Context, base backend.B) context.Co ntext { | 35 func (o *CacheOptions) WrapBackend(c context.Context, base backend.B) context.Co ntext { |
| 25 return backend.WithFactory(c, func(c context.Context) backend.B { | 36 return backend.WithFactory(c, func(c context.Context) backend.B { |
| 26 // Start with our base Backend. | 37 // Start with our base Backend. |
| 27 be := base | 38 be := base |
| 28 | 39 |
| 40 // If our datastore cache is available, fetch settings to see if it's | |
| 41 // enabled. | |
| 42 if o.DatastoreCacheAvailable { | |
| 43 switch s, err := gaeconfig.FetchCachedSettings(c); err { | |
| 44 case nil: | |
| 45 // Successfully fetched settings, is our datasto re cache enabled? | |
| 46 switch s.DatastoreCacheMode { | |
| 47 case gaeconfig.DSCacheEnabled, gaeconfig.DSCache Strict: | |
| 48 // Datastore cache is enabled, add a cac hing backend layer. | |
| 49 exp := time.Duration(s.CacheExpirationSe c) * time.Second | |
| 50 if exp > 0 { | |
| 51 // The cache is enable. Install it into our backend. | |
|
iannucci
2017/01/21 00:32:23
enabled
dnj
2017/01/21 02:00:02
Done.
| |
| 52 locker := &dsCacheLocker{} | |
| 53 dsCfg := datastore.Config{ | |
| 54 RefreshInterval: exp, | |
| 55 FailOpen: s.Datas toreCacheMode == gaeconfig.DSCacheEnabled, | |
| 56 LockerFunc: func(co ntext.Context) datastorecache.Locker { return locker }, | |
|
iannucci
2017/01/21 00:32:24
I don't suppose it would make sense to have a Lock
dnj
2017/01/21 02:00:02
Acknowledged.
| |
| 57 } | |
| 58 be = dsCfg.Backend(be) | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 default: | |
| 63 log.WithError(err).Debugf(c, "Failed to fetch da tastore cache settings.") | |
|
iannucci
2017/01/21 00:32:23
Debug? Warning?
dnj
2017/01/21 02:00:02
Warning is fine.
| |
| 64 } | |
| 65 } | |
| 66 | |
| 29 // Add a proccache-based config cache. | 67 // Add a proccache-based config cache. |
| 30 if o.CacheExpiration > 0 { | 68 if o.CacheExpiration > 0 { |
| 31 be = caching.ProcCache(be, o.CacheExpiration) | 69 be = caching.ProcCache(be, o.CacheExpiration) |
| 32 } | 70 } |
| 33 | 71 |
| 34 return be | 72 return be |
| 35 }) | 73 }) |
| 36 } | 74 } |
| 75 | |
| 76 type dsCacheLocker struct { | |
| 77 p mutexpool.P | |
| 78 } | |
| 79 | |
| 80 func (l *dsCacheLocker) TryWithLock(c context.Context, key string, fn func(conte xt.Context) error) (err error) { | |
| 81 l.p.WithMutex(key, func() { | |
| 82 err = fn(c) | |
| 83 }) | |
| 84 return | |
| 85 } | |
| OLD | NEW |