From 8181ff3f8abbe5c2a4dd4e0547cf7a89acb29bf8 Mon Sep 17 00:00:00 2001 From: Atul Sinha Date: Mon, 28 Oct 2024 15:44:17 +0530 Subject: [PATCH] race condition handling --- go.mod | 1 + go.sum | 2 ++ remote/go.mod | 2 +- remote/go.sum | 1 + viper.go | 23 ++++++++++++++++++++++- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index c856e47c4..b6a052c39 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.21.0 require ( github.com/fsnotify/fsnotify v1.7.0 github.com/go-viper/mapstructure/v2 v2.2.1 + github.com/mitchellh/mapstructure v1.5.0 github.com/pelletier/go-toml/v2 v2.2.3 github.com/sagikazarmark/locafero v0.6.0 github.com/spf13/afero v1.11.0 diff --git a/go.sum b/go.sum index 4cce7da5c..26ca25874 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/remote/go.mod b/remote/go.mod index cb41e0061..ad69b761b 100644 --- a/remote/go.mod +++ b/remote/go.mod @@ -24,7 +24,7 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-viper/mapstructure/v2 v2.1.0 // indirect + github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect diff --git a/remote/go.sum b/remote/go.sum index 70f62a985..9d3375e9c 100644 --- a/remote/go.sum +++ b/remote/go.sum @@ -70,6 +70,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= diff --git a/viper.go b/viper.go index f900e58b1..c6ac278db 100644 --- a/viper.go +++ b/viper.go @@ -24,6 +24,7 @@ import ( "encoding/csv" "errors" "fmt" + "github.com/mitchellh/mapstructure" "io" "log/slog" "os" @@ -36,7 +37,6 @@ import ( "time" "github.com/fsnotify/fsnotify" - "github.com/go-viper/mapstructure/v2" "github.com/spf13/afero" "github.com/spf13/cast" "github.com/spf13/pflag" @@ -188,6 +188,8 @@ type Viper struct { experimentalFinder bool experimentalBindStruct bool + + kvMutex sync.RWMutex } // New returns an initialized Viper instance. @@ -201,7 +203,11 @@ func New() *Viper { v.parents = []string{} v.override = make(map[string]any) v.defaults = make(map[string]any) + + v.kvMutex.Lock() v.kvstore = make(map[string]any) + v.kvMutex.Unlock() + v.pflags = make(map[string]FlagValue) v.env = make(map[string][]string) v.aliases = make(map[string]string) @@ -1237,7 +1243,10 @@ func (v *Viper) find(lcaseKey string, flagDefault bool) any { } // K/V store next + v.kvMutex.RLock() + defer v.kvMutex.RUnlock() val = v.searchMap(v.kvstore, path) + if val != nil { return val } @@ -1397,10 +1406,14 @@ func (v *Viper) registerAlias(alias, key string) { delete(v.config, alias) v.config[key] = val } + + v.kvMutex.Lock() if val, ok := v.kvstore[alias]; ok { delete(v.kvstore, alias) v.kvstore[key] = val } + v.kvMutex.Unlock() + if val, ok := v.defaults[alias]; ok { delete(v.defaults, alias) v.defaults[key] = val @@ -1847,7 +1860,11 @@ func (v *Viper) AllKeys() []string { m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags)) m = v.mergeFlatMap(m, castMapStringSliceToMapInterface(v.env)) m = v.flattenAndMergeMap(m, v.config, "") + + v.kvMutex.Lock() m = v.flattenAndMergeMap(m, v.kvstore, "") + v.kvMutex.Unlock() + m = v.flattenAndMergeMap(m, v.defaults, "") // convert set of paths to list @@ -2025,7 +2042,11 @@ func (v *Viper) DebugTo(w io.Writer) { fmt.Fprintf(w, "Override:\n%#v\n", v.override) fmt.Fprintf(w, "PFlags:\n%#v\n", v.pflags) fmt.Fprintf(w, "Env:\n%#v\n", v.env) + + v.kvMutex.RLock() fmt.Fprintf(w, "Key/Value Store:\n%#v\n", v.kvstore) + v.kvMutex.RUnlock() + fmt.Fprintf(w, "Config:\n%#v\n", v.config) fmt.Fprintf(w, "Defaults:\n%#v\n", v.defaults) }