Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 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 gaemiddleware | 5 package gaemiddleware |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "fmt" | 8 "fmt" |
| 9 | 9 |
| 10 "golang.org/x/net/context" | 10 "golang.org/x/net/context" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 // LoggingLevel is logging level to set the default logger to. | 25 // LoggingLevel is logging level to set the default logger to. |
| 26 // | 26 // |
| 27 // Log entries below this level will be completely ignored. They won't e ven | 27 // Log entries below this level will be completely ignored. They won't e ven |
| 28 // reach GAE logging service. Default is logging.Debug (all logs hit log ging | 28 // reach GAE logging service. Default is logging.Debug (all logs hit log ging |
| 29 // service). | 29 // service). |
| 30 LoggingLevel logging.Level `json:"logging_level"` | 30 LoggingLevel logging.Level `json:"logging_level"` |
| 31 | 31 |
| 32 // DisableDSCache is true to disable dscache (the memcache layer on top of | 32 // DisableDSCache is true to disable dscache (the memcache layer on top of |
| 33 // the datastore). | 33 // the datastore). |
| 34 DisableDSCache settings.YesOrNo `json:"disable_dscache"` | 34 DisableDSCache settings.YesOrNo `json:"disable_dscache"` |
| 35 | |
| 36 // AnalyticsID is a Google Analytics ID an admin can set to enable Analy tics. | |
| 37 // The app must support analytics for this to work. | |
| 38 AnalyticsID string `json:"analytics_id"` | |
|
Vadim Sh.
2016/08/26 21:55:05
I'm confused, why do you have it in two places? Le
hinoka
2016/08/26 23:11:35
This was a mistake (well, vestige), deleted.
| |
| 35 } | 39 } |
| 36 | 40 |
| 37 // fetchCachedSettings fetches gaeSettings from the settings store or panics. | 41 // fetchCachedSettings fetches gaeSettings from the settings store or panics. |
| 38 // | 42 // |
| 39 // Uses in-process global cache to avoid hitting datastore often. The cache | 43 // Uses in-process global cache to avoid hitting datastore often. The cache |
| 40 // expiration time is 1 min (see gaesettings.expirationTime), meaning | 44 // expiration time is 1 min (see gaesettings.expirationTime), meaning |
| 41 // the instance will refetch settings once a minute (blocking only one unlucky | 45 // the instance will refetch settings once a minute (blocking only one unlucky |
| 42 // request to do so). | 46 // request to do so). |
| 43 // | 47 // |
| 44 // Panics only if there's no cached value (i.e. it is the first call to this | 48 // Panics only if there's no cached value (i.e. it is the first call to this |
| 45 // function in this process ever) and datastore operation fails. It is a good | 49 // function in this process ever) and datastore operation fails. It is a good |
| 46 // idea to implement /_ah/warmup to warm this up. | 50 // idea to implement /_ah/warmup to warm this up. |
| 47 func fetchCachedSettings(c context.Context) gaeSettings { | 51 func fetchCachedSettings(c context.Context) gaeSettings { |
| 48 s := gaeSettings{} | 52 s := gaeSettings{} |
| 49 switch err := settings.Get(c, settingsKey, &s); { | 53 switch err := settings.Get(c, settingsKey, &s); { |
| 50 case err == nil: | 54 case err == nil: |
| 51 return s | 55 return s |
| 52 case err == settings.ErrNoSettings: | 56 case err == settings.ErrNoSettings: |
| 53 // Defaults. | 57 // Defaults. |
| 54 return gaeSettings{ | 58 return gaeSettings{ |
| 55 LoggingLevel: logging.Debug, | 59 LoggingLevel: logging.Debug, |
| 56 DisableDSCache: false, | 60 DisableDSCache: false, |
| 61 AnalyticsID: "", | |
| 57 } | 62 } |
| 58 default: | 63 default: |
| 59 panic(fmt.Errorf("could not fetch GAE settings - %s", err)) | 64 panic(fmt.Errorf("could not fetch GAE settings - %s", err)) |
| 60 } | 65 } |
| 61 } | 66 } |
| 62 | 67 |
| 63 //////////////////////////////////////////////////////////////////////////////// | 68 //////////////////////////////////////////////////////////////////////////////// |
| 64 // UI for GAE settings. | 69 // UI for GAE settings. |
| 65 | 70 |
| 66 type settingsUIPage struct { | 71 type settingsUIPage struct { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 93 settings.YesOrNoField(settings.UIField{ | 98 settings.YesOrNoField(settings.UIField{ |
| 94 ID: "DisableDSCache", | 99 ID: "DisableDSCache", |
| 95 Title: "Disable datastore cache", | 100 Title: "Disable datastore cache", |
| 96 Help: `Usually caching is a good thing and it can be lef t enabled. You may | 101 Help: `Usually caching is a good thing and it can be lef t enabled. You may |
| 97 want to disable it if memcache is having issues that prevent entity writes to | 102 want to disable it if memcache is having issues that prevent entity writes to |
| 98 succeed. See <a href="https://godoc.org/github.com/luci/gae/filter/dscache"> | 103 succeed. See <a href="https://godoc.org/github.com/luci/gae/filter/dscache"> |
| 99 dscache documentation</a> for more information. Toggling this on and off has | 104 dscache documentation</a> for more information. Toggling this on and off has |
| 100 consequences: <b>memcache is completely flushed</b>. Do not toy with this | 105 consequences: <b>memcache is completely flushed</b>. Do not toy with this |
| 101 setting.`, | 106 setting.`, |
| 102 }), | 107 }), |
| 108 { | |
| 109 ID: "AnalyticsID", | |
| 110 Title: "Google Analytics Trakcing ID", | |
| 111 Type: settings.UIFieldText, | |
| 112 Help: `Tracking ID used for Google Analytics. Filling t his in does not | |
| 113 by itself add analytics to the app, it must be embedded in the HTML templates | |
| 114 by calling <TODO: WHAT?>`, | |
| 115 }, | |
| 103 }, nil | 116 }, nil |
| 104 } | 117 } |
| 105 | 118 |
| 106 func (settingsUIPage) ReadSettings(c context.Context) (map[string]string, error) { | 119 func (settingsUIPage) ReadSettings(c context.Context) (map[string]string, error) { |
| 107 s := gaeSettings{} | 120 s := gaeSettings{} |
| 108 err := settings.GetUncached(c, settingsKey, &s) | 121 err := settings.GetUncached(c, settingsKey, &s) |
| 109 if err != nil && err != settings.ErrNoSettings { | 122 if err != nil && err != settings.ErrNoSettings { |
| 110 return nil, err | 123 return nil, err |
| 111 } | 124 } |
| 112 return map[string]string{ | 125 return map[string]string{ |
| 113 "LoggingLevel": s.LoggingLevel.String(), | 126 "LoggingLevel": s.LoggingLevel.String(), |
| 114 "DisableDSCache": s.DisableDSCache.String(), | 127 "DisableDSCache": s.DisableDSCache.String(), |
| 128 "AnalyticsID": s.AnalyticsID, | |
| 115 }, nil | 129 }, nil |
| 116 } | 130 } |
| 117 | 131 |
| 118 func (settingsUIPage) WriteSettings(c context.Context, values map[string]string, who, why string) error { | 132 func (settingsUIPage) WriteSettings(c context.Context, values map[string]string, who, why string) error { |
| 119 modified := gaeSettings{} | 133 modified := gaeSettings{} |
| 120 if err := modified.LoggingLevel.Set(values["LoggingLevel"]); err != nil { | 134 if err := modified.LoggingLevel.Set(values["LoggingLevel"]); err != nil { |
| 121 return err | 135 return err |
| 122 } | 136 } |
| 123 if err := modified.DisableDSCache.Set(values["DisableDSCache"]); err != nil { | 137 if err := modified.DisableDSCache.Set(values["DisableDSCache"]); err != nil { |
| 124 return err | 138 return err |
| 125 } | 139 } |
| 140 modified.AnalyticsID = values["AnalyticsID"] | |
| 126 | 141 |
| 127 // When switching dscache back on, wipe memcache. | 142 // When switching dscache back on, wipe memcache. |
| 128 existing := gaeSettings{} | 143 existing := gaeSettings{} |
| 129 err := settings.GetUncached(c, settingsKey, &existing) | 144 err := settings.GetUncached(c, settingsKey, &existing) |
| 130 if err != nil && err != settings.ErrNoSettings { | 145 if err != nil && err != settings.ErrNoSettings { |
| 131 return err | 146 return err |
| 132 } | 147 } |
| 133 if existing.DisableDSCache && !modified.DisableDSCache { | 148 if existing.DisableDSCache && !modified.DisableDSCache { |
| 134 logging.Warningf(c, "DSCache was reenabled, wiping memcache") | 149 logging.Warningf(c, "DSCache was reenabled, wiping memcache") |
| 135 if err := memcache.Get(c).Flush(); err != nil { | 150 if err := memcache.Get(c).Flush(); err != nil { |
| 136 return err | 151 return err |
| 137 } | 152 } |
| 138 } | 153 } |
| 139 | 154 |
| 140 return settings.SetIfChanged(c, settingsKey, &modified, who, why) | 155 return settings.SetIfChanged(c, settingsKey, &modified, who, why) |
| 141 } | 156 } |
| 142 | 157 |
| 143 func init() { | 158 func init() { |
| 144 settings.RegisterUIPage(settingsKey, settingsUIPage{}) | 159 settings.RegisterUIPage(settingsKey, settingsUIPage{}) |
| 145 } | 160 } |
| OLD | NEW |