Add config change signal and concurrent getters

This commit is contained in:
Daniel 2018-10-22 17:05:59 +02:00
parent ff919c7342
commit ea9592a536
3 changed files with 96 additions and 2 deletions

View file

@ -133,12 +133,12 @@ func registerAsDatabase() error {
PrimaryAPI: "",
})
if err != nil {
return nil
return err
}
controller, err := database.InjectDatabase("config", &ConfigStorageInterface{})
if err != nil {
return nil
return err
}
dbController = controller

74
config/get-safe.go Normal file
View file

@ -0,0 +1,74 @@
package config
import "sync"
type safe struct{}
var (
// Concurrent makes concurrency safe get methods available.
Concurrent = &safe{}
)
// GetAsString returns a function that returns the wanted string with high performance.
func (cs *safe) GetAsString(name string, fallback string) StringOption {
valid := getValidityFlag()
value := findStringValue(name, fallback)
var lock sync.Mutex
return func() string {
lock.Lock()
defer lock.Unlock()
if !valid.IsSet() {
valid = getValidityFlag()
value = findStringValue(name, fallback)
}
return value
}
}
// GetAsStringArray returns a function that returns the wanted string with high performance.
func (cs *safe) GetAsStringArray(name string, fallback []string) StringArrayOption {
valid := getValidityFlag()
value := findStringArrayValue(name, fallback)
var lock sync.Mutex
return func() []string {
lock.Lock()
defer lock.Unlock()
if !valid.IsSet() {
valid = getValidityFlag()
value = findStringArrayValue(name, fallback)
}
return value
}
}
// GetAsInt returns a function that returns the wanted int with high performance.
func (cs *safe) GetAsInt(name string, fallback int64) IntOption {
valid := getValidityFlag()
value := findIntValue(name, fallback)
var lock sync.Mutex
return func() int64 {
lock.Lock()
defer lock.Unlock()
if !valid.IsSet() {
valid = getValidityFlag()
value = findIntValue(name, fallback)
}
return value
}
}
// GetAsBool returns a function that returns the wanted int with high performance.
func (cs *safe) GetAsBool(name string, fallback bool) BoolOption {
valid := getValidityFlag()
value := findBoolValue(name, fallback)
var lock sync.Mutex
return func() bool {
lock.Lock()
defer lock.Unlock()
if !valid.IsSet() {
valid = getValidityFlag()
value = findBoolValue(name, fallback)
}
return value
}
}

View file

@ -19,8 +19,24 @@ var (
// ErrInvalidOptionType is returned by SetConfigOption and SetDefaultConfigOption if given an unsupported option type.
ErrInvalidOptionType = errors.New("invalid option value type")
changedSignal = make(chan struct{}, 0)
)
// Changed signals if any config option was changed.
func Changed() <-chan struct{} {
configLock.RLock()
defer configLock.RUnlock()
return changedSignal
}
// triggerChange signals listeners that a config option was changed.
func triggerChange() {
// must be locked!
close(changedSignal)
changedSignal = make(chan struct{}, 0)
}
// setConfig sets the (prioritized) user defined config.
func setConfig(m map[string]interface{}) error {
configLock.Lock()
@ -29,6 +45,7 @@ func setConfig(m map[string]interface{}) error {
resetValidityFlag()
go pushFullUpdate()
triggerChange()
return nil
}
@ -41,6 +58,7 @@ func SetDefaultConfig(m map[string]interface{}) error {
resetValidityFlag()
go pushFullUpdate()
triggerChange()
return nil
}
@ -124,6 +142,7 @@ func setConfigOption(name string, value interface{}, push bool) error {
if err == nil {
resetValidityFlag()
go saveConfig()
triggerChange()
}
return err
@ -155,6 +174,7 @@ func setDefaultConfigOption(name string, value interface{}, push bool) error {
if err == nil {
resetValidityFlag()
triggerChange()
}
return err