erp_server/config/internal/config.go
2022-10-09 11:39:33 +08:00

91 lines
1.8 KiB
Go

package internal
import (
"errors"
"github.com/go-kratos/kratos/v2/log"
"sync"
// init encoding
_ "github.com/go-kratos/kratos/v2/encoding/json"
_ "github.com/go-kratos/kratos/v2/encoding/proto"
_ "github.com/go-kratos/kratos/v2/encoding/xml"
_ "github.com/go-kratos/kratos/v2/encoding/yaml"
)
var (
// ErrNotFound is key not found.
ErrNotFound = errors.New("key not found")
// ErrTypeAssert is type assert error.
ErrTypeAssert = errors.New("type assert error")
_ Config = (*config)(nil)
)
// Observer is config observer.
type Observer func(string, Value)
// Config is a config interface.
type Config interface {
Load() error
Bytes() ([]byte, error)
Value(key string) Value
}
type config struct {
opts options
reader Reader
cached sync.Map
observers sync.Map
log *log.Helper
}
// New new a config with options.
func New(opts ...Option) Config {
o := options{
logger: log.DefaultLogger,
decoder: defaultDecoder,
resolver: defaultResolver,
}
for _, opt := range opts {
opt(&o)
}
return &config{
opts: o,
reader: newReader(o),
log: log.NewHelper(o.logger),
}
}
func (c *config) Load() error {
for _, src := range c.opts.sources {
kvs, err := src.Load()
if err != nil {
return err
}
if err = c.reader.Merge(kvs...); err != nil {
c.log.Errorf("failed to merge config source: %v", err)
return err
}
}
if err := c.reader.Resolve(); err != nil {
c.log.Errorf("failed to resolve config source: %v", err)
return err
}
return nil
}
func (c *config) Bytes() ([]byte, error) {
return c.reader.Bytes()
}
func (c *config) Value(key string) Value {
if v, ok := c.cached.Load(key); ok {
return v.(Value)
}
if v, ok := c.reader.Value(key); ok {
c.cached.Store(key, v)
return v
}
return &errValue{err: ErrNotFound}
}