Skip to content

Commit

Permalink
register listeners for config changes
Browse files Browse the repository at this point in the history
  • Loading branch information
garmr-ulfr committed Jul 30, 2024
1 parent 109a69a commit abd8ab1
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
5 changes: 2 additions & 3 deletions flashlight.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ func (f *Flashlight) StartBackgroundServices() (func(), error) {

stopBypass := services.StartBypassService(f.addProxyListener, f.configDir, f.userConfig)

onConfig := func(old, new *services.ClientConfig) {
services.OnConfigChange(func(old, new *services.ClientConfig) {
var country string
if old != nil {
country = old.GetCountry()
Expand All @@ -472,7 +472,7 @@ func (f *Flashlight) StartBackgroundServices() (func(), error) {

proxyMap := f.convertNewProxyConfToOld(new.GetProxy().GetProxies())
f.notifyProxyListeners(proxyMap, config.Fetched)
}
})

configOpts := &services.ConfigOptions{
SaveDir: f.configDir,
Expand All @@ -481,7 +481,6 @@ func (f *Flashlight) StartBackgroundServices() (func(), error) {
UserConfig: f.userConfig,
Sticky: false,
RoundTripper: proxied.ParallelPreferChained(),
OnConfig: onConfig,
}

setConfigFlagOpts(configOpts, f.flagsAsMap)
Expand Down
35 changes: 28 additions & 7 deletions services/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,6 @@ type ConfigOptions struct {
PollInterval time.Duration
// PollJitter specifies the max amount of jitter to add to the poll interval.
PollJitter time.Duration

// OnConfig is a callback that is called when a new config is received.
OnConfig func(old, new *ClientConfig)
}

type configService struct {
Expand All @@ -92,6 +89,9 @@ type configService struct {
done chan struct{}
running bool
logger golog.Logger

// listeners is a list of functions to call when the config changes.
listeners []func(old, new *ClientConfig)
}

var (
Expand All @@ -114,8 +114,6 @@ func StartConfigService(opts *ConfigOptions) (StopFn, error) {
switch {
case opts.RoundTripper == nil:
return nil, errors.New("RoundTripper is required")
case opts.OnConfig == nil:
return nil, errors.New("OnConfig is required")
case opts.OriginURL == "":
return nil, errors.New("OriginURL is required")
}
Expand Down Expand Up @@ -188,7 +186,7 @@ func (cs *configService) init() error {

cs.clientInfo.Country = conf.Country
cs.clientConfig.Store(conf)
cs.opts.OnConfig(nil, conf)
cs.notifyListeners(nil, conf)

return nil
}
Expand Down Expand Up @@ -244,7 +242,7 @@ func (cs *configService) fetchConfig() (int64, error) {

cs.updateClientInfo(newConf)
old := cs.clientConfig.Swap(newConf)
cs.opts.OnConfig(old.(*ClientConfig), newConf)
cs.notifyListeners(old.(*ClientConfig), newConf)

return sleep, nil
}
Expand Down Expand Up @@ -385,3 +383,26 @@ func GetCountry() string {

return conf.GetCountry()
}

// OnConfigChange registers a function to be called when the config changes. This allows callers to
// respond to changes in the config without having to poll for changes.
func OnConfigChange(fn func(old, new *ClientConfig)) {
configServiceMu.Lock()
if _configService.listeners == nil {
_configService.listeners = make([]func(old, new *ClientConfig), 0, 1)
}

_configService.listeners = append(_configService.listeners, fn)
configServiceMu.Unlock()
}

func (cs *configService) notifyListeners(old, new *ClientConfig) {
configServiceMu.Lock()
listeners := cs.listeners
configServiceMu.Unlock()
// TODO: should we clone the configs before passing them to the listeners?
for _, fn := range listeners {
// don't block the config service
go fn(old, new)
}
}

0 comments on commit abd8ab1

Please sign in to comment.