gcfg包增加配置文件自动更新检测特性

This commit is contained in:
John
2018-04-18 16:00:47 +08:00
parent 157d15302c
commit 31c72feba8
5 changed files with 45 additions and 34 deletions

View File

@ -10,17 +10,17 @@ package gcfg
import (
"sync"
"time"
"strings"
"gitee.com/johng/gf/g/os/gfile"
"gitee.com/johng/gf/g/container/gmap"
"gitee.com/johng/gf/g/encoding/gjson"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/container/gset"
"gitee.com/johng/gf/g/os/gfsnotify"
)
const (
gDEFAULT_CONFIG_FILE = "config.yml" // 默认的配置管理文件名称
gDEFAULT_AUTO_CHECK_INTERVAL = 3 // 自动检测文件更新间隔(秒)
gDEFAULT_CONFIG_FILE = "config.yml" // 默认的配置管理文件名称
)
// 配置管理对象
@ -28,20 +28,18 @@ type Config struct {
mu sync.RWMutex // 并发互斥锁
path *gtype.String // 配置文件存放目录,绝对路径
jsons *gmap.StringInterfaceMap // 配置文件对象
checks *gmap.StringIntMap // 配置文件自动更新检查数组
fpaths *gset.StringSet // 已经监控的文件路径Set
closed *gtype.Bool // 是否已经被close
}
// 生成一个配置管理对象
func New(path string) *Config {
c := &Config {
return &Config {
path : gtype.NewString(path),
jsons : gmap.NewStringInterfaceMap(),
checks : gmap.NewStringIntMap(),
fpaths : gset.NewStringSet(),
closed : gtype.NewBool(),
}
c.startAutoUpdateLoop()
return c
}
// 判断从哪个配置文件中获取内容,返回配置文件的绝对路径
@ -77,7 +75,7 @@ func (c *Config) getJson(file []string) *gjson.Json {
}
if j, err := gjson.Load(fpath); err == nil {
c.jsons.Set(fpath, j)
c.checks.Set(fpath, int(gfile.MTime(fpath)))
c.AddMonitor(fpath)
return j
}
return nil
@ -167,26 +165,16 @@ func (c *Config) Close() {
c.closed.Set(true)
}
// 异步文件更新判断,当外部更新了配置文件后,缓存的配置会更新
func (c *Config) startAutoUpdateLoop() {
go func() {
for {
time.Sleep(gDEFAULT_AUTO_CHECK_INTERVAL*time.Second)
if c.closed.Val() {
// 添加文件监控
func (c *Config) AddMonitor(path string) {
if !c.fpaths.Contains(path) {
c.fpaths.Add(path)
gfsnotify.Add(path, func(event *gfsnotify.Event) {
if event.IsRemove() {
gfsnotify.Remove(event.Path)
return
}
m := make(map[string]int)
c.checks.Iterator(func(k string, v int) bool {
mtime := int(gfile.MTime(k))
if mtime > v {
m[k] = mtime
c.jsons.Remove(k)
}
return true
})
if len(m) > 0 {
c.checks.BatchSet(m)
}
}
}()
}
c.jsons.Remove(event.Path)
})
}
}

View File

@ -5,6 +5,7 @@
// You can obtain one at https://gitee.com/johng/gf.
// 文件监控.
// 使用时需要注意的是,一旦一个文件被删除,那么对其的监控将会失效。
package gfsnotify
import (
@ -151,6 +152,11 @@ func (w *Watcher) startEventLoop() {
for {
if v := w.events.PopFront(); v != nil {
event := v.(*Event)
// 如果是文件删除时间,判断该文件是否存在,如果存在,那么将此事件认为“假删除”,并重新添加监控
if event.IsRemove() && gfile.Exists(event.Path){
w.watcher.Add(event.Path)
continue
}
if l := w.callbacks.Get(event.Path); l != nil {
grpool.Add(func() {
for _, v := range l.(*glist.List).FrontAll() {

View File

@ -21,5 +21,6 @@ memcache:
- host: 192.168.0.102
port: 11211
expire: 60
viewpath : /home/www/templates/
serverpath : /home/www/server/

View File

@ -3,14 +3,10 @@ package main
import (
"fmt"
"gitee.com/johng/gf/g/os/gcfg"
"time"
)
func main() {
c := gcfg.New("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/os/gcfg")
fmt.Println(c.GetArray("memcache"))
time.Sleep(10*time.Second)
// 给你10秒钟的时间修改配置下一次读取会自动更新
fmt.Println(c.GetArray("memcache"))
}

View File

@ -0,0 +1,20 @@
package main
import (
"fmt"
"time"
"gitee.com/johng/gf/g/os/gcfg"
"gitee.com/johng/gf/g/os/gtime"
)
func main() {
c := gcfg.New("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/os/gcfg")
// 每隔1秒打印当前配置项值用户可手动在外部修改文件内容gcfg读取到的配置项值会即时得到更新
gtime.SetInterval(time.Second, func() bool {
fmt.Println(c.Get("viewpath"))
return true
})
select {}
}