Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: server/internal/logdog/service/config/config.go

Issue 1970463005: LogDog: enable services to fetch project configs (Closed) Base URL: https://github.com/luci/luci-go@logdog-project-coordinator-config
Patch Set: Updated patchset dependency Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package config 5 package config
6 6
7 import ( 7 import (
8 "errors"
9 "fmt"
8 "time" 10 "time"
9 11
10 "github.com/golang/protobuf/proto" 12 "github.com/golang/protobuf/proto"
11 "github.com/luci/luci-go/common/clock" 13 "github.com/luci/luci-go/common/clock"
12 "github.com/luci/luci-go/common/config" 14 "github.com/luci/luci-go/common/config"
13 log "github.com/luci/luci-go/common/logging" 15 log "github.com/luci/luci-go/common/logging"
14 "github.com/luci/luci-go/common/proto/logdog/svcconfig" 16 "github.com/luci/luci-go/common/proto/logdog/svcconfig"
17 "github.com/luci/luci-go/server/proccache"
15 "golang.org/x/net/context" 18 "golang.org/x/net/context"
16 ) 19 )
17 20
18 // Options is the set of options used to set up a Manager. 21 // Options is the set of options used to set up a Manager.
19 // 22 //
20 // The configuration is loaded from a svcconfig.Config protobuf. 23 // The configuration is loaded from a svcconfig.Config protobuf.
21 type Options struct { 24 type Options struct {
22 // Config is the configuration service to load from. 25 // Config is the configuration service to load from.
23 Config config.Interface 26 Config config.Interface
24 27
28 // ProjectID is the project's application ID. This is used to load
29 // project-specific configurations.
30 //
31 // If empty, project-specific configurations cannot be loaded.
32 ProjectID string
nodir 2016/05/18 16:25:51 Better call it AppID so it is unambiguous. Luci co
dnj (Google) 2016/05/18 16:50:31 I'm using the term, "project ID", here, which is c
nodir 2016/05/18 17:02:19 I don't understand. This is app id, see how is it
33
25 // ConfigSet is the name of the ConfigSet to load. 34 // ConfigSet is the name of the ConfigSet to load.
26 ConfigSet string 35 ConfigSet string
27 // ServiceConfigPath is the name of the LogDog service config within the 36 // ServiceConfigPath is the name of the LogDog service config within the
28 // ConfigSet. 37 // ConfigSet.
29 ServiceConfigPath string 38 ServiceConfigPath string
30 39
40 // ProjectConfigCacheDuration is the amount of time to cache a project's
41 // configuration. If this is <= 0, the project config will be fetched ea ch
42 // time it's requested.
43 ProjectConfigCacheDuration time.Duration
44
31 // KillCheckInterval, if >0, starts a goroutine that polls every interva l to 45 // KillCheckInterval, if >0, starts a goroutine that polls every interva l to
32 // see if the configuration has changed. If it has, KillFunc will be inv oked. 46 // see if the configuration has changed. If it has, KillFunc will be inv oked.
33 KillCheckInterval time.Duration 47 KillCheckInterval time.Duration
34 // KillFunc is the function that will be called if a configuration hash change 48 // KillFunc is the function that will be called if a configuration hash change
35 // has been observed. 49 // has been observed.
36 KillFunc func() 50 KillFunc func()
37 } 51 }
38 52
39 func (o *Options) getConfig(hashOnly bool) (*config.Config, error) { 53 func (o *Options) getConfig(hashOnly bool) (*config.Config, error) {
40 return o.Config.GetConfig(o.ConfigSet, o.ServiceConfigPath, hashOnly) 54 return o.Config.GetConfig(o.ConfigSet, o.ServiceConfigPath, hashOnly)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 // It can also periodically refresh that configuration and invoke a shutdown 98 // It can also periodically refresh that configuration and invoke a shutdown
85 // function if its content changes. 99 // function if its content changes.
86 type Manager struct { 100 type Manager struct {
87 o *Options 101 o *Options
88 102
89 // cfg is the initial configuration. 103 // cfg is the initial configuration.
90 cfg svcconfig.Config 104 cfg svcconfig.Config
91 // cfgHash is the hash string of the original config. 105 // cfgHash is the hash string of the original config.
92 cfgHash string 106 cfgHash string
93 107
108 // projectConfigCache is a cache of project-specific configs. They will
109 // eventually timeout and get refreshed according to options.
110 projectConfigCache proccache.Cache
111
94 // configChangedC will contain the result of the most recent configurati on 112 // configChangedC will contain the result of the most recent configurati on
95 // change poll operation. The configuration change poller will block unt il 113 // change poll operation. The configuration change poller will block unt il
96 // that result is consumed. 114 // that result is consumed.
97 configChangedC chan struct{} 115 configChangedC chan struct{}
98 // changePollerCancelFunc is the cancel function to call to stop the 116 // changePollerCancelFunc is the cancel function to call to stop the
99 // configuration poller. 117 // configuration poller.
100 changePollerCancelFunc func() 118 changePollerCancelFunc func()
101 } 119 }
102 120
103 // NewManager generates a new Manager and loads the initial configuration. 121 // NewManager generates a new Manager and loads the initial configuration.
(...skipping 19 matching lines...) Expand all
123 } 141 }
124 142
125 return &m, nil 143 return &m, nil
126 } 144 }
127 145
128 // Config returns the service configuration instance. 146 // Config returns the service configuration instance.
129 func (m *Manager) Config() *svcconfig.Config { 147 func (m *Manager) Config() *svcconfig.Config {
130 return &m.cfg 148 return &m.cfg
131 } 149 }
132 150
151 // ProjectConfig returns the project configuration.
152 func (m *Manager) ProjectConfig(c context.Context, project config.ProjectName) ( *svcconfig.ProjectConfig, error) {
153 projectID := m.o.ProjectID
nodir 2016/05/18 16:25:51 This is app id
dnj (Google) 2016/05/18 16:50:31 Acknowledged.
154 if projectID == "" {
155 return nil, errors.New("no app ID specified")
156 }
157
158 v, err := proccache.GetOrMake(c, project, func() (interface{}, time.Dura tion, error) {
159 configSet := fmt.Sprintf("projects/%s", project)
160 configPath := fmt.Sprintf("%s.cfg", projectID)
161 cfg, err := m.o.Config.GetConfig(configSet, configPath, false)
162 if err != nil {
163 log.Fields{
164 log.ErrorKey: err,
165 "project": project,
166 }.Errorf(c, "Failed to load config.")
167 return nil, 0, err
168 }
169
170 var pcfg svcconfig.ProjectConfig
171 if err := proto.UnmarshalText(cfg.Content, &pcfg); err != nil {
172 log.Fields{
173 log.ErrorKey: err,
174 "project": project,
175 "hash": cfg.ContentHash,
176 "configSet": configSet,
177 "path": configPath,
nodir 2016/05/18 16:25:51 Sort?
dnj (Google) 2016/05/18 16:50:31 I don't think you need to pay so much attention to
178 }.Errorf(c, "Failed to unmarshal project config.")
179 }
180
181 log.Fields{
182 "cacheDuration": m.o.ProjectConfigCacheDuration,
183 "project": project,
184 "hash": cfg.ContentHash,
185 "configSet": configSet,
186 "path": configPath,
nodir 2016/05/18 16:25:51 Sort?
dnj (Google) 2016/05/18 16:50:31 Acknowledged.
187 }.Infof(c, "Refreshed project configuration.")
188 return &pcfg, m.o.ProjectConfigCacheDuration, nil
189 })
190 if err != nil {
191 return nil, err
192 }
193 return v.(*svcconfig.ProjectConfig), nil
194 }
195
133 // Close terminates the config change poller and blocks until it has finished. 196 // Close terminates the config change poller and blocks until it has finished.
134 // 197 //
135 // Close must be called in order to ensure that Go scheduler properly schedules 198 // Close must be called in order to ensure that Go scheduler properly schedules
136 // the goroutine. 199 // the goroutine.
137 func (m *Manager) Close() { 200 func (m *Manager) Close() {
138 // If our config change poller is running, cancel and reap it. 201 // If our config change poller is running, cancel and reap it.
139 if m.changePollerCancelFunc != nil { 202 if m.changePollerCancelFunc != nil {
140 m.changePollerCancelFunc() 203 m.changePollerCancelFunc()
141 <-m.configChangedC 204 <-m.configChangedC
142 } 205 }
143 } 206 }
144 207
145 func (m *Manager) reloadConfig(c context.Context) error { 208 func (m *Manager) reloadConfig(c context.Context) error {
146 cfg, err := m.o.getConfig(false) 209 cfg, err := m.o.getConfig(false)
147 if err != nil { 210 if err != nil {
148 return err 211 return err
149 } 212 }
150 213
151 if err := proto.UnmarshalText(cfg.Content, &m.cfg); err != nil { 214 if err := proto.UnmarshalText(cfg.Content, &m.cfg); err != nil {
152 log.Fields{ 215 log.Fields{
153 log.ErrorKey: err, 216 log.ErrorKey: err,
154 "hash": cfg.ContentHash, 217 "hash": cfg.ContentHash,
155 }.Errorf(c, "Failed to unmarshal configuration.") 218 }.Errorf(c, "Failed to unmarshal configuration.")
156 return err 219 return err
157 } 220 }
158 m.cfgHash = cfg.ContentHash 221 m.cfgHash = cfg.ContentHash
159 return nil 222 return nil
160 } 223 }
OLDNEW
« no previous file with comments | « no previous file | server/internal/logdog/service/service.go » ('j') | server/internal/logdog/service/service.go » ('J')

Powered by Google App Engine
This is Rietveld 408576698