| OLD | NEW |
| 1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 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 dscache | 5 package dscache |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "sync" | 8 "sync" |
| 9 "time" | 9 "time" |
| 10 | 10 |
| 11 » "github.com/luci/gae/service/datastore" | 11 » ds "github.com/luci/gae/service/datastore" |
| 12 "github.com/luci/gae/service/info" | 12 "github.com/luci/gae/service/info" |
| 13 » "github.com/luci/gae/service/memcache" | 13 » mc "github.com/luci/gae/service/memcache" |
| 14 |
| 14 "github.com/luci/luci-go/common/clock" | 15 "github.com/luci/luci-go/common/clock" |
| 16 |
| 15 "golang.org/x/net/context" | 17 "golang.org/x/net/context" |
| 16 ) | 18 ) |
| 17 | 19 |
| 18 // GlobalConfig is the entity definition for dscache's global configuration. | 20 // GlobalConfig is the entity definition for dscache's global configuration. |
| 19 // | 21 // |
| 20 // It's Enable field can be set to false to cause all dscache operations | 22 // It's Enable field can be set to false to cause all dscache operations |
| 21 // (read and write) to cease in a given application. | 23 // (read and write) to cease in a given application. |
| 22 // | 24 // |
| 23 // This should be manipulated in the GLOBAL (e.g. empty) namespace only. When | 25 // This should be manipulated in the GLOBAL (e.g. empty) namespace only. When |
| 24 // written there, it affects activity in all namespaces. | 26 // written there, it affects activity in all namespaces. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 } | 69 } |
| 68 | 70 |
| 69 globalEnabledLock.Lock() | 71 globalEnabledLock.Lock() |
| 70 defer globalEnabledLock.Unlock() | 72 defer globalEnabledLock.Unlock() |
| 71 // just in case we raced | 73 // just in case we raced |
| 72 if now.Before(globalEnabledNextCheck) { | 74 if now.Before(globalEnabledNextCheck) { |
| 73 return globalEnabled | 75 return globalEnabled |
| 74 } | 76 } |
| 75 | 77 |
| 76 // always go to the default namespace | 78 // always go to the default namespace |
| 77 » c, err := info.Get(c).Namespace("") | 79 » c, err := info.Namespace(c, "") |
| 78 if err != nil { | 80 if err != nil { |
| 79 return true | 81 return true |
| 80 } | 82 } |
| 81 cfg := &GlobalConfig{Enable: true} | 83 cfg := &GlobalConfig{Enable: true} |
| 82 » if err := datastore.Get(c).Get(cfg); err != nil && err != datastore.ErrN
oSuchEntity { | 84 » if err := ds.Get(c, cfg); err != nil && err != ds.ErrNoSuchEntity { |
| 83 return true | 85 return true |
| 84 } | 86 } |
| 85 globalEnabled = cfg.Enable | 87 globalEnabled = cfg.Enable |
| 86 globalEnabledNextCheck = now.Add(GlobalEnabledCheckInterval) | 88 globalEnabledNextCheck = now.Add(GlobalEnabledCheckInterval) |
| 87 return globalEnabled | 89 return globalEnabled |
| 88 } | 90 } |
| 89 | 91 |
| 90 // SetGlobalEnable is a convenience function for manipulating the GlobalConfig. | 92 // SetGlobalEnable is a convenience function for manipulating the GlobalConfig. |
| 91 // | 93 // |
| 92 // It's meant to be called from admin handlers on your app to turn dscache | 94 // It's meant to be called from admin handlers on your app to turn dscache |
| 93 // functionality on or off in emergencies. | 95 // functionality on or off in emergencies. |
| 94 func SetGlobalEnable(c context.Context, memcacheEnabled bool) error { | 96 func SetGlobalEnable(c context.Context, memcacheEnabled bool) error { |
| 95 // always go to the default namespace | 97 // always go to the default namespace |
| 96 » c, err := info.Get(c).Namespace("") | 98 » c, err := info.Namespace(c, "") |
| 97 if err != nil { | 99 if err != nil { |
| 98 return err | 100 return err |
| 99 } | 101 } |
| 100 » return datastore.Get(c).RunInTransaction(func(c context.Context) error { | 102 » return ds.RunInTransaction(c, func(c context.Context) error { |
| 101 » » ds := datastore.Get(c) | |
| 102 cfg := &GlobalConfig{Enable: true} | 103 cfg := &GlobalConfig{Enable: true} |
| 103 » » if err := ds.Get(cfg); err != nil && err != datastore.ErrNoSuchE
ntity { | 104 » » if err := ds.Get(c, cfg); err != nil && err != ds.ErrNoSuchEntit
y { |
| 104 return err | 105 return err |
| 105 } | 106 } |
| 106 if cfg.Enable == memcacheEnabled { | 107 if cfg.Enable == memcacheEnabled { |
| 107 return nil | 108 return nil |
| 108 } | 109 } |
| 109 cfg.Enable = memcacheEnabled | 110 cfg.Enable = memcacheEnabled |
| 110 if memcacheEnabled { | 111 if memcacheEnabled { |
| 111 // when going false -> true, wipe memcache. | 112 // when going false -> true, wipe memcache. |
| 112 » » » if err := memcache.Get(c).Flush(); err != nil { | 113 » » » if err := mc.Flush(c); err != nil { |
| 113 return err | 114 return err |
| 114 } | 115 } |
| 115 } | 116 } |
| 116 » » return ds.Put(cfg) | 117 » » return ds.Put(c, cfg) |
| 117 }, nil) | 118 }, nil) |
| 118 } | 119 } |
| OLD | NEW |