代码拉取完成,页面将自动刷新
package config
import (
"gitee.com/dennis-kk/service-box-go/util/config/loader"
"gitee.com/dennis-kk/service-box-go/util/config/loader/memory"
"gitee.com/dennis-kk/service-box-go/util/config/reader"
"gitee.com/dennis-kk/service-box-go/util/config/reader/yaml"
"gitee.com/dennis-kk/service-box-go/util/config/source"
"sync"
)
type config struct {
sync.RWMutex
opts Options
// the current snapshot
snap *loader.Snapshot
// the current values
values reader.Values
// watcher reload 触发回调
watcher OnReloadCallBack
// 退出监听
exit chan bool
}
func newConfig(opts ...Option) (Config, error) {
c := config{
exit: make(chan bool),
}
err := c.Init(opts...)
if err != nil {
return nil, err
}
return &c, nil
}
func (c *config) Init(opts ...Option) error {
c.opts = Options{
Reader: yaml.NewReader(),
}
for _, o := range opts {
o(&c.opts)
}
// default loader uses the configured reader
if c.opts.Loader == nil {
c.opts.Loader = memory.NewLoader(loader.WithReader(c.opts.Reader))
}
err := c.opts.Loader.Load(c.opts.Source...)
if err != nil {
return err
}
c.snap, err = c.opts.Loader.Snapshot()
if err != nil {
return err
}
c.values, err = c.opts.Reader.Values(c.snap.ChangeSet)
if err != nil {
return err
}
return nil
}
func (c *config) Options() *Options {
return &(c.opts)
}
func (c *config) Map() map[string]interface{} {
c.RLock()
defer c.RUnlock()
return c.values.Map()
}
func (c *config) Scan(v interface{}) error {
c.RLock()
defer c.RUnlock()
return c.values.Scan(v)
}
func (c *config) Close() error {
err := c.opts.Loader.Close()
close(c.exit)
return err
}
func (c *config) Get(path ...string) reader.Value {
c.RLock()
defer c.RUnlock()
if c.values != nil {
return c.values.Get(path...)
}
// no value
return newValue()
}
func (c *config) Bytes() []byte {
c.RLock()
defer c.RUnlock()
if c.values == nil {
return []byte{}
}
return c.values.Bytes()
}
func (c *config) Load(sources ...source.Source) error {
if err := c.opts.Loader.Load(sources...); err != nil {
return err
}
snap, err := c.opts.Loader.Snapshot()
if err != nil {
return err
}
c.Lock()
defer c.Unlock()
c.snap = snap
vals, err := c.opts.Reader.Values(snap.ChangeSet)
if err != nil {
return err
}
c.values = vals
return nil
}
func (c *config) Start() error {
go c.loop()
return nil
}
func (c *config) Watch(cb OnReloadCallBack) {
c.Lock()
c.watcher = cb
c.Unlock()
}
// loop 主循环,用于处理监听,更新配置
func (c *config) loop() {
for {
select {
case <-c.exit:
return
default:
}
snapshot, err := c.opts.Loader.Next()
if err != nil {
return
}
// 转换为新配置
values, err := c.opts.Reader.Values(snapshot.ChangeSet)
if err != nil {
//TODO: 添加日志
continue
}
// 上锁 更新配置
c.Lock()
c.values = values
c.snap = snapshot
c.Unlock()
// 启动一个新的协程,用于处理回调
if c.watcher != nil {
go c.watcher(c)
}
}
}
func (c *config) String() string {
return "config"
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。