From 14617d40b75751d24623e471ff77c35069489838 Mon Sep 17 00:00:00 2001 From: Kuisong Tong Date: Mon, 13 Nov 2023 20:17:12 -0800 Subject: [PATCH] remove Watch from global (#56) --- README.md | 18 ++++----------- benchmark_test.go | 24 +++++--------------- config_test.go | 58 +++++++++++++++++++++++------------------------ doc.go | 3 +-- global.go | 12 ---------- global_test.go | 23 ------------------- 6 files changed, 41 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index 438f02df..e5013767 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ configuration source(s) (implementation) it actually wants to use. Something lik func main() { // Create the global Config that loads configuration // from embed file system and environment variables. - cfg, err := konf.New( + config, err := konf.New( konf.WithLoader( fs.New(config, "config/config.json"), env.New(env.WithPrefix("server")), @@ -40,24 +40,16 @@ configuration source(s) (implementation) it actually wants to use. Something lik if err != nil { // Handle error here. } - konf.SetGlobal(cfg) - - // ... other setup code ... - } -``` - -Application also can watch the changes of configuration like: - -``` - func main() { - // ... setup global Config ... + // Watch the changes of configuration. go func() { - if err := konf.Watch(ctx); err != nil { + if err := config.Watch(ctx); err != nil { // Handle error here. } } + konf.SetGlobal(config) + // ... other setup code ... } ``` diff --git a/benchmark_test.go b/benchmark_test.go index dad3a372..3f78f4c6 100644 --- a/benchmark_test.go +++ b/benchmark_test.go @@ -4,8 +4,6 @@ package konf_test import ( - "context" - "sync/atomic" "testing" "github.com/ktong/konf" @@ -42,27 +40,17 @@ func BenchmarkGet(b *testing.B) { assert.Equal(b, "v", value) } -func BenchmarkWatch(b *testing.B) { - watcher := mapWatcher(make(chan map[string]any)) - config, err := konf.New(konf.WithLoader(watcher)) +func BenchmarkUnmarshal(b *testing.B) { + config, err := konf.New(konf.WithLoader(mapLoader{"k": "v"})) assert.NoError(b, err) konf.SetGlobal(config) - - assert.Equal(b, "string", konf.Get[string]("config")) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go func() { - assert.NoError(b, konf.Watch(ctx)) - }() b.ResetTimer() - var cfg atomic.Value - konf.OnChange(func() { - cfg.Store(konf.Get[string]("config")) - }) + var value string for i := 0; i < b.N; i++ { - watcher.change(map[string]any{"config": "changed"}) + _ = konf.Unmarshal("k", &value) } b.StopTimer() - assert.Equal(b, "changed", cfg.Load()) + + assert.Equal(b, "v", value) } diff --git a/config_test.go b/config_test.go index 4c37d9d1..44cda7ba 100644 --- a/config_test.go +++ b/config_test.go @@ -25,38 +25,38 @@ func TestConfig_Unmarshal(t *testing.T) { { description: "empty values", assert: func(config konf.Config) { - var cfg string - assert.NoError(t, config.Unmarshal("config", &cfg)) - assert.Equal(t, "", cfg) + var value string + assert.NoError(t, config.Unmarshal("config", &value)) + assert.Equal(t, "", value) }, }, { description: "nil loader", opts: []konf.Option{konf.WithLoader(nil)}, assert: func(config konf.Config) { - var cfg string - assert.NoError(t, config.Unmarshal("config", &cfg)) - assert.Equal(t, "", cfg) + var value string + assert.NoError(t, config.Unmarshal("config", &value)) + assert.Equal(t, "", value) }, }, { description: "for primary type", opts: []konf.Option{konf.WithLoader(mapLoader{"config": "string"})}, assert: func(config konf.Config) { - var cfg string - assert.NoError(t, config.Unmarshal("config", &cfg)) - assert.Equal(t, "string", cfg) + var value string + assert.NoError(t, config.Unmarshal("config", &value)) + assert.Equal(t, "string", value) }, }, { description: "config for struct", opts: []konf.Option{konf.WithLoader(mapLoader{"config": "struct"})}, assert: func(config konf.Config) { - var cfg struct { + var value struct { Config string } - assert.NoError(t, config.Unmarshal("", &cfg)) - assert.Equal(t, "struct", cfg.Config) + assert.NoError(t, config.Unmarshal("", &value)) + assert.Equal(t, "struct", value.Config) }, }, { @@ -71,9 +71,9 @@ func TestConfig_Unmarshal(t *testing.T) { ), }, assert: func(config konf.Config) { - var cfg string - assert.NoError(t, config.Unmarshal("config.nest", &cfg)) - assert.Equal(t, "string", cfg) + var value string + assert.NoError(t, config.Unmarshal("config.nest", &value)) + assert.Equal(t, "string", value) }, }, { @@ -89,9 +89,9 @@ func TestConfig_Unmarshal(t *testing.T) { ), }, assert: func(config konf.Config) { - var cfg string - assert.NoError(t, config.Unmarshal("config_nest", &cfg)) - assert.Equal(t, "string", cfg) + var value string + assert.NoError(t, config.Unmarshal("config_nest", &value)) + assert.Equal(t, "string", value) }, }, { @@ -106,9 +106,9 @@ func TestConfig_Unmarshal(t *testing.T) { ), }, assert: func(config konf.Config) { - var cfg string - assert.NoError(t, config.Unmarshal("config.nest", &cfg)) - assert.Equal(t, "", cfg) + var value string + assert.NoError(t, config.Unmarshal("config.nest", &value)) + assert.Equal(t, "", value) }, }, } @@ -139,9 +139,9 @@ func TestConfig_Watch(t *testing.T) { config, err := konf.New(konf.WithLoader(watcher)) assert.NoError(t, err) - var cfg string - assert.NoError(t, config.Unmarshal("config", &cfg)) - assert.Equal(t, "string", cfg) + var value string + assert.NoError(t, config.Unmarshal("config", &value)) + assert.Equal(t, "string", value) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -149,14 +149,14 @@ func TestConfig_Watch(t *testing.T) { assert.NoError(t, config.Watch(ctx)) }() - var newCfg atomic.Value + var newValue atomic.Value config.OnChange(func(unmarshaler konf.Unmarshaler) { - var cfg string - assert.NoError(t, config.Unmarshal("config", &cfg)) - newCfg.Store(cfg) + var value string + assert.NoError(t, config.Unmarshal("config", &value)) + newValue.Store(value) }) watcher.change(map[string]any{"config": "changed"}) - assert.Equal(t, "changed", newCfg.Load()) + assert.Equal(t, "changed", newValue.Load()) } type mapWatcher chan map[string]any diff --git a/doc.go b/doc.go index 2df20f22..eb29b1b5 100644 --- a/doc.go +++ b/doc.go @@ -12,9 +12,9 @@ // and reloads latest configuration when it has changes from a Watcher interface. // // Config has following main methods: +// - Config.Watch reloads configuration when it changes. // - Config.Unmarshal loads configuration under the given path // into the given object pointed to by target. -// - Config.Watch reloads configuration when it changes. // - Config.OnChange register callback on configuration changes. // // # Global Config @@ -26,6 +26,5 @@ // It returns zero value if there is an error while getting configuration. // - Unmarshal loads configuration under the given path // into the given object pointed to by target. -// - Watch reloads configuration when it changes. // - OnChange register callback on configuration changes. package konf diff --git a/global.go b/global.go index a49d8aeb..ed34ad5c 100644 --- a/global.go +++ b/global.go @@ -4,7 +4,6 @@ package konf import ( - "context" "log/slog" "reflect" "sync" @@ -46,17 +45,6 @@ func Unmarshal(path string, target any) error { return global.Unmarshal(path, target) } -// Watch watches and updates configuration when it changes. -// It blocks until ctx is done, or the service returns an error. -// -// It only can be called once. Call after first has no effects. -func Watch(ctx context.Context) error { - mux.RLock() - defer mux.RUnlock() - - return global.Watch(ctx) -} - // OnChange executes the given onChange function while the value of any given path // (or any value is no paths) have been changed. // diff --git a/global_test.go b/global_test.go index fbe4cb07..c2eb559d 100644 --- a/global_test.go +++ b/global_test.go @@ -5,9 +5,7 @@ package konf_test import ( "bytes" - "context" "log" - "sync/atomic" "testing" "github.com/ktong/konf" @@ -51,24 +49,3 @@ func TestGet_error(t *testing.T) { " path=config type=bool\n" assert.Equal(t, expected, buf.String()) } - -func TestWatch(t *testing.T) { - watcher := mapWatcher(make(chan map[string]any)) - config, err := konf.New(konf.WithLoader(watcher)) - assert.NoError(t, err) - konf.SetGlobal(config) - assert.Equal(t, "string", konf.Get[string]("config")) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go func() { - assert.NoError(t, konf.Watch(ctx)) - }() - - var cfg atomic.Value - konf.OnChange(func() { - cfg.Store(konf.Get[string]("config")) - }) - watcher.change(map[string]any{"config": "changed"}) - assert.Equal(t, "changed", cfg.Load()) -}