From 31c72feba8b34d2dc3acebb3ecb9d11d84a24dec Mon Sep 17 00:00:00 2001 From: John Date: Wed, 18 Apr 2018 16:00:47 +0800 Subject: [PATCH] =?UTF-8?q?gcfg=E5=8C=85=E5=A2=9E=E5=8A=A0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/os/gcfg/gcfg.go | 48 +++++++++++++-------------------- g/os/gfsnotify/gfsnotify.go | 6 +++++ geg/os/gcfg/config.yml | 1 + geg/os/gcfg/gcfg2.go | 4 --- geg/os/gcfg/gcfg_auto_update.go | 20 ++++++++++++++ 5 files changed, 45 insertions(+), 34 deletions(-) create mode 100644 geg/os/gcfg/gcfg_auto_update.go diff --git a/g/os/gcfg/gcfg.go b/g/os/gcfg/gcfg.go index ef4d70bd7..dd5d454cf 100644 --- a/g/os/gcfg/gcfg.go +++ b/g/os/gcfg/gcfg.go @@ -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) - } - } - }() -} \ No newline at end of file + c.jsons.Remove(event.Path) + }) + } +} diff --git a/g/os/gfsnotify/gfsnotify.go b/g/os/gfsnotify/gfsnotify.go index 3197f0cf0..00bb189cd 100644 --- a/g/os/gfsnotify/gfsnotify.go +++ b/g/os/gfsnotify/gfsnotify.go @@ -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() { diff --git a/geg/os/gcfg/config.yml b/geg/os/gcfg/config.yml index 704940d6d..3848021f8 100644 --- a/geg/os/gcfg/config.yml +++ b/geg/os/gcfg/config.yml @@ -21,5 +21,6 @@ memcache: - host: 192.168.0.102 port: 11211 expire: 60 + viewpath : /home/www/templates/ serverpath : /home/www/server/ \ No newline at end of file diff --git a/geg/os/gcfg/gcfg2.go b/geg/os/gcfg/gcfg2.go index 1859f9312..4616e48fe 100644 --- a/geg/os/gcfg/gcfg2.go +++ b/geg/os/gcfg/gcfg2.go @@ -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")) } diff --git a/geg/os/gcfg/gcfg_auto_update.go b/geg/os/gcfg/gcfg_auto_update.go new file mode 100644 index 000000000..130f1a79e --- /dev/null +++ b/geg/os/gcfg/gcfg_auto_update.go @@ -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 {} +} +