mirror of
https://gitee.com/johng/gf
synced 2026-06-07 10:22:11 +08:00
gcfg包增加配置文件自动更新检测特性
This commit is contained in:
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -21,5 +21,6 @@ memcache:
|
||||
- host: 192.168.0.102
|
||||
port: 11211
|
||||
expire: 60
|
||||
|
||||
viewpath : /home/www/templates/
|
||||
serverpath : /home/www/server/
|
||||
@ -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"))
|
||||
}
|
||||
|
||||
|
||||
20
geg/os/gcfg/gcfg_auto_update.go
Normal file
20
geg/os/gcfg/gcfg_auto_update.go
Normal 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 {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user