Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | |
| 3 // that can be found in the LICENSE file. | |
| 4 | |
| 5 package config | |
| 6 | |
| 7 import ( | |
| 8 "time" | |
| 9 | |
| 10 "github.com/luci/luci-go/common/clock" | |
| 11 "github.com/luci/luci-go/common/errors" | |
| 12 log "github.com/luci/luci-go/common/logging" | |
| 13 "github.com/luci/luci-go/luci_config/common/cfgtypes" | |
| 14 "github.com/luci/luci-go/luci_config/server/cfgclient" | |
| 15 | |
| 16 "golang.org/x/net/context" | |
| 17 ) | |
| 18 | |
| 19 // ChangePoller polls a configuration files for changes. If it changes, | |
| 20 // the OnChange function will be called and the polling will stop. | |
|
iannucci
2017/01/21 00:09:12
what's the reason for having the loop stop on the
dnj
2017/01/21 01:17:54
The application will quit after this, so there's n
| |
| 21 type ChangePoller struct { | |
| 22 // ConfigSet is the slice of config paths to watch. | |
| 23 ConfigSet cfgtypes.ConfigSet | |
| 24 // Path is the path of the config to watch. | |
| 25 Path string | |
| 26 | |
| 27 // if the configuration has changed. If it has, KillFunc will be invoked . | |
|
iannucci
2017/01/21 00:09:12
something went wrong with this comment I think. Al
dnj
2017/01/21 01:17:54
Fixed.
| |
| 28 CheckInterval time.Duration | |
| 29 // OnChange is the function that will be called if a configuration hash change | |
| 30 // has been observed. | |
| 31 OnChange func() | |
| 32 | |
| 33 // ContentHash is the config's hash. If empty, it will be populated when first | |
| 34 // polled. | |
| 35 ContentHash string | |
| 36 } | |
| 37 | |
| 38 // Run starts polling for changes. It will stop when the Context is cancelled. | |
| 39 func (p *ChangePoller) Run(c context.Context) { | |
| 40 if p.CheckInterval <= 0 { | |
| 41 return | |
| 42 } | |
| 43 | |
| 44 for { | |
| 45 if err := c.Err(); err != nil { | |
|
iannucci
2017/01/21 00:09:12
so remember that thing we talked about last febura
dnj
2017/01/21 01:17:54
Done.
| |
| 46 log.WithError(err).Warningf(c, "Terminating poll loop: c ontext has been cancelled.") | |
| 47 return | |
| 48 } | |
| 49 | |
| 50 log.Fields{ | |
| 51 "timeout": p.CheckInterval, | |
| 52 }.Debugf(c, "Entering change check poll loop...") | |
| 53 if tr := clock.Sleep(c, p.CheckInterval); tr.Incomplete() { | |
| 54 log.WithError(tr.Err).Debugf(c, "Context cancelled, shut ting down change poller.") | |
| 55 return | |
| 56 } | |
| 57 | |
| 58 log.Infof(c, "Change check timeout triggered, checking configura tion...") | |
| 59 lastHash := p.ContentHash | |
| 60 switch err := p.refresh(c); { | |
| 61 case err != nil: | |
| 62 log.WithError(err).Errorf(c, "Failed to refresh config." ) | |
| 63 | |
| 64 case lastHash != p.ContentHash: | |
| 65 log.Fields{ | |
| 66 "originalHash": lastHash, | |
| 67 "newHash": p.ContentHash, | |
| 68 }.Warningf(c, "Configuration content hash has changed.") | |
| 69 if p.OnChange != nil { | |
| 70 p.OnChange() | |
| 71 } | |
| 72 return | |
| 73 | |
| 74 default: | |
| 75 log.Fields{ | |
| 76 "currentHash": lastHash, | |
| 77 }.Debugf(c, "Content hash matches.") | |
| 78 } | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 func (p *ChangePoller) refresh(c context.Context) error { | |
| 83 var meta cfgclient.Meta | |
| 84 if err := cfgclient.Get(c, cfgclient.AsService, p.ConfigSet, p.Path, nil , &meta); err != nil { | |
| 85 return errors.Annotate(err).Reason("failed to reload config %(co nfigSet)s :: %(path)s"). | |
| 86 D("configSet", p.ConfigSet).D("path", p.Path).Err() | |
|
iannucci
2017/01/21 00:09:12
how would
return errors.Annotate(err).
Reas
dnj
2017/01/21 01:17:54
Taller, but sure.
| |
| 87 } | |
| 88 | |
| 89 p.ContentHash = meta.ContentHash | |
| 90 return nil | |
| 91 } | |
| OLD | NEW |