Chromium Code Reviews| Index: server/internal/logdog/service/config/config.go |
| diff --git a/server/internal/logdog/service/config/config.go b/server/internal/logdog/service/config/config.go |
| index 6fed7b09ce6fb62617593b884e9d935c6f706f59..37dacd0dffdf0f8998f6c76d285d9b2d71ce7ec5 100644 |
| --- a/server/internal/logdog/service/config/config.go |
| +++ b/server/internal/logdog/service/config/config.go |
| @@ -5,6 +5,8 @@ |
| package config |
| import ( |
| + "errors" |
| + "fmt" |
| "time" |
| "github.com/golang/protobuf/proto" |
| @@ -12,6 +14,7 @@ import ( |
| "github.com/luci/luci-go/common/config" |
| log "github.com/luci/luci-go/common/logging" |
| "github.com/luci/luci-go/common/proto/logdog/svcconfig" |
| + "github.com/luci/luci-go/server/proccache" |
| "golang.org/x/net/context" |
| ) |
| @@ -22,12 +25,23 @@ type Options struct { |
| // Config is the configuration service to load from. |
| Config config.Interface |
| + // ProjectID is the project's application ID. This is used to load |
| + // project-specific configurations. |
| + // |
| + // If empty, project-specific configurations cannot be loaded. |
| + 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
|
| + |
| // ConfigSet is the name of the ConfigSet to load. |
| ConfigSet string |
| // ServiceConfigPath is the name of the LogDog service config within the |
| // ConfigSet. |
| ServiceConfigPath string |
| + // ProjectConfigCacheDuration is the amount of time to cache a project's |
| + // configuration. If this is <= 0, the project config will be fetched each |
| + // time it's requested. |
| + ProjectConfigCacheDuration time.Duration |
| + |
| // KillCheckInterval, if >0, starts a goroutine that polls every interval to |
| // see if the configuration has changed. If it has, KillFunc will be invoked. |
| KillCheckInterval time.Duration |
| @@ -91,6 +105,10 @@ type Manager struct { |
| // cfgHash is the hash string of the original config. |
| cfgHash string |
| + // projectConfigCache is a cache of project-specific configs. They will |
| + // eventually timeout and get refreshed according to options. |
| + projectConfigCache proccache.Cache |
| + |
| // configChangedC will contain the result of the most recent configuration |
| // change poll operation. The configuration change poller will block until |
| // that result is consumed. |
| @@ -130,6 +148,51 @@ func (m *Manager) Config() *svcconfig.Config { |
| return &m.cfg |
| } |
| +// ProjectConfig returns the project configuration. |
| +func (m *Manager) ProjectConfig(c context.Context, project config.ProjectName) (*svcconfig.ProjectConfig, error) { |
| + projectID := m.o.ProjectID |
|
nodir
2016/05/18 16:25:51
This is app id
dnj (Google)
2016/05/18 16:50:31
Acknowledged.
|
| + if projectID == "" { |
| + return nil, errors.New("no app ID specified") |
| + } |
| + |
| + v, err := proccache.GetOrMake(c, project, func() (interface{}, time.Duration, error) { |
| + configSet := fmt.Sprintf("projects/%s", project) |
| + configPath := fmt.Sprintf("%s.cfg", projectID) |
| + cfg, err := m.o.Config.GetConfig(configSet, configPath, false) |
| + if err != nil { |
| + log.Fields{ |
| + log.ErrorKey: err, |
| + "project": project, |
| + }.Errorf(c, "Failed to load config.") |
| + return nil, 0, err |
| + } |
| + |
| + var pcfg svcconfig.ProjectConfig |
| + if err := proto.UnmarshalText(cfg.Content, &pcfg); err != nil { |
| + log.Fields{ |
| + log.ErrorKey: err, |
| + "project": project, |
| + "hash": cfg.ContentHash, |
| + "configSet": configSet, |
| + "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
|
| + }.Errorf(c, "Failed to unmarshal project config.") |
| + } |
| + |
| + log.Fields{ |
| + "cacheDuration": m.o.ProjectConfigCacheDuration, |
| + "project": project, |
| + "hash": cfg.ContentHash, |
| + "configSet": configSet, |
| + "path": configPath, |
|
nodir
2016/05/18 16:25:51
Sort?
dnj (Google)
2016/05/18 16:50:31
Acknowledged.
|
| + }.Infof(c, "Refreshed project configuration.") |
| + return &pcfg, m.o.ProjectConfigCacheDuration, nil |
| + }) |
| + if err != nil { |
| + return nil, err |
| + } |
| + return v.(*svcconfig.ProjectConfig), nil |
| +} |
| + |
| // Close terminates the config change poller and blocks until it has finished. |
| // |
| // Close must be called in order to ensure that Go scheduler properly schedules |