2019-05-31 01:11:13 +03:00
|
|
|
// Package config is an interface for dynamic configuration.
|
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-12-04 02:28:45 +03:00
|
|
|
"errors"
|
2021-08-03 00:24:40 +03:00
|
|
|
"time"
|
2020-12-04 02:28:45 +03:00
|
|
|
)
|
2019-05-31 01:11:13 +03:00
|
|
|
|
2021-04-27 08:32:47 +03:00
|
|
|
// DefaultConfig default config
|
|
|
|
var DefaultConfig Config = NewConfig()
|
2019-05-31 01:11:13 +03:00
|
|
|
|
2021-08-04 00:37:56 +03:00
|
|
|
// DefaultWatcherMinInterval default min interval for poll changes
|
|
|
|
var DefaultWatcherMinInterval = 5 * time.Second
|
|
|
|
|
2021-09-28 23:43:43 +03:00
|
|
|
// DefaultWatcherMaxInterval default max interval for poll changes
|
2021-08-04 00:37:56 +03:00
|
|
|
var DefaultWatcherMaxInterval = 9 * time.Second
|
2021-08-03 00:24:40 +03:00
|
|
|
|
2020-08-29 18:08:21 +03:00
|
|
|
var (
|
2020-12-13 13:26:44 +03:00
|
|
|
// ErrCodecMissing is returned when codec needed and not specified
|
|
|
|
ErrCodecMissing = errors.New("codec missing")
|
2020-12-13 13:10:04 +03:00
|
|
|
// ErrInvalidStruct is returned when the target struct is invalid
|
|
|
|
ErrInvalidStruct = errors.New("invalid struct specified")
|
2020-12-04 02:28:45 +03:00
|
|
|
// ErrWatcherStopped is returned when source watcher has been stopped
|
|
|
|
ErrWatcherStopped = errors.New("watcher stopped")
|
2020-08-29 18:08:21 +03:00
|
|
|
)
|
|
|
|
|
2019-05-31 01:11:13 +03:00
|
|
|
// Config is an interface abstraction for dynamic configuration
|
|
|
|
type Config interface {
|
2021-06-20 23:57:13 +03:00
|
|
|
// Name returns name of config
|
2021-01-29 16:18:17 +03:00
|
|
|
Name() string
|
2020-03-12 21:13:03 +03:00
|
|
|
// Init the config
|
|
|
|
Init(opts ...Option) error
|
2020-03-31 19:13:21 +03:00
|
|
|
// Options in the config
|
|
|
|
Options() Options
|
2020-12-04 02:28:45 +03:00
|
|
|
// Load config from sources
|
2021-06-20 23:57:13 +03:00
|
|
|
Load(context.Context, ...LoadOption) error
|
2020-12-04 02:28:45 +03:00
|
|
|
// Save config to sources
|
2021-06-20 23:57:13 +03:00
|
|
|
Save(context.Context, ...SaveOption) error
|
2021-08-03 00:24:40 +03:00
|
|
|
// Watch a config for changes
|
|
|
|
Watch(context.Context, ...WatchOption) (Watcher, error)
|
2021-06-20 23:57:13 +03:00
|
|
|
// String returns config type name
|
2020-12-04 02:28:45 +03:00
|
|
|
String() string
|
2019-05-31 01:11:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Watcher is the config watcher
|
2021-06-20 23:57:13 +03:00
|
|
|
type Watcher interface {
|
2021-08-03 00:24:40 +03:00
|
|
|
// Next blocks until update happens or error returned
|
|
|
|
Next() (map[string]interface{}, error)
|
|
|
|
// Stop stops watcher
|
2021-06-20 23:57:13 +03:00
|
|
|
Stop() error
|
|
|
|
}
|
2020-12-18 03:37:18 +03:00
|
|
|
|
|
|
|
// Load loads config from config sources
|
2021-07-01 15:56:22 +03:00
|
|
|
func Load(ctx context.Context, cs []Config, opts ...LoadOption) error {
|
2020-12-18 03:37:18 +03:00
|
|
|
var err error
|
|
|
|
for _, c := range cs {
|
2020-12-20 23:08:40 +03:00
|
|
|
if err = c.Init(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-07-01 15:56:22 +03:00
|
|
|
if err = c.Load(ctx, opts...); err != nil {
|
2020-12-18 03:37:18 +03:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2021-09-30 01:24:16 +03:00
|
|
|
|
|
|
|
var (
|
|
|
|
DefaultAfterLoad = func(ctx context.Context, c Config) error {
|
|
|
|
for _, fn := range c.Options().AfterLoad {
|
|
|
|
if err := fn(ctx, c); err != nil {
|
|
|
|
c.Options().Logger.Errorf(ctx, "%s AfterLoad err: %v", c.String(), err)
|
|
|
|
if !c.Options().AllowFail {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultAfterSave = func(ctx context.Context, c Config) error {
|
|
|
|
for _, fn := range c.Options().AfterSave {
|
|
|
|
if err := fn(ctx, c); err != nil {
|
|
|
|
c.Options().Logger.Errorf(ctx, "%s AfterSave err: %v", c.String(), err)
|
|
|
|
if !c.Options().AllowFail {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultBeforeLoad = func(ctx context.Context, c Config) error {
|
|
|
|
for _, fn := range c.Options().BeforeLoad {
|
|
|
|
if err := fn(ctx, c); err != nil {
|
|
|
|
c.Options().Logger.Errorf(ctx, "%s BeforeLoad err: %v", c.String(), err)
|
|
|
|
if !c.Options().AllowFail {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultBeforeSave = func(ctx context.Context, c Config) error {
|
|
|
|
for _, fn := range c.Options().BeforeSave {
|
|
|
|
if err := fn(ctx, c); err != nil {
|
|
|
|
c.Options().Logger.Errorf(ctx, "%s BeforeSavec err: %v", c.String(), err)
|
|
|
|
if !c.Options().AllowFail {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
)
|