Skip to content

Commit

Permalink
config: Add RegisterNotifier
Browse files Browse the repository at this point in the history
This allows to trigger a callback when a specific config key is modified
or unset, and to do some higher level actions in response to that.
This allows to remove the somewhat ugly UpdateDefaults() call from
the generic code in config.go, and to add this to RegisterSettings
instead where it makes more sense.
  • Loading branch information
cfergeau authored and anjannath committed May 29, 2023
1 parent cbbe913 commit 98cb394
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
35 changes: 32 additions & 3 deletions pkg/crc/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,22 @@ const (
invalidType = "Type %T for configuration property '%s' is invalid"
)

type ValueChangedFunc func(config *Config, key string, value interface{})

type Config struct {
storage RawStorage
secretStorage RawStorage
settingsByName map[string]Setting

valueChangeNotifiers map[string]ValueChangedFunc
}

func New(storage, secretStorage RawStorage) *Config {
return &Config{
storage: storage,
secretStorage: secretStorage,
settingsByName: make(map[string]Setting),
storage: storage,
secretStorage: secretStorage,
settingsByName: make(map[string]Setting),
valueChangeNotifiers: map[string]ValueChangedFunc{},
}
}

Expand Down Expand Up @@ -145,6 +150,8 @@ func (c *Config) Set(key string, value interface{}) (string, error) {
}
}

c.valueChangeNotify(key, value)

return c.settingsByName[key].callbackFn(key, castValue), nil
}

Expand All @@ -163,9 +170,31 @@ func (c *Config) Unset(key string) (string, error) {
return "", err
}
}

c.valueChangeNotify(key, nil)

return fmt.Sprintf("Successfully unset configuration property '%s'", key), nil
}

func (c *Config) RegisterNotifier(key string, changeNotifier ValueChangedFunc) error {
if _, hasKey := c.valueChangeNotifiers[key]; hasKey {
return fmt.Errorf("Config change notifier already registered for %s", key)
}

c.valueChangeNotifiers[key] = changeNotifier

return nil
}

func (c *Config) valueChangeNotify(key string, value interface{}) {
changeNotifier, hasKey := c.valueChangeNotifiers[key]
if !hasKey {
return
}

changeNotifier(c, key, value)
}

func (c *Config) Get(key string) SettingValue {
setting, ok := c.settingsByName[key]
if !ok {
Expand Down
23 changes: 23 additions & 0 deletions pkg/crc/config/viper_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,26 @@ func TestTwoInstancesSetAndUnsetSameConfiguration(t *testing.T) {
assert.Equal(t, 4, config2.Get(cpus).Value)
assert.Equal(t, 4, config1.Get(cpus).Value)
}

func TestNotifier(t *testing.T) {
dir := t.TempDir()
configFile := filepath.Join(dir, "crc.json")

config, err := newTestConfig(configFile, "CRC")
require.NoError(t, err)

var notified = false
err = config.RegisterNotifier(CPUs, func(config *Config, key string, value interface{}) {
notified = true
require.Equal(t, key, CPUs)
assert.Equal(t, SettingValue{
Value: value,
IsDefault: false,
}, config.Get(cpus))

})
require.NoError(t, err)
_, err = config.Set(cpus, 5)
assert.NoError(t, err)
require.True(t, notified)
}

0 comments on commit 98cb394

Please sign in to comment.