gf/g/os/gfsnotify/gfsnotify.go

99 lines
3.2 KiB
Go
Raw Normal View History

2018-04-17 18:58:22 +08:00
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
// 文件监控.
2018-10-31 19:00:28 +08:00
// 使用时需要注意的是,一旦一个文件被删除,那么对其的监控将会失效;如果删除的是目录,那么该目录及其下的文件都将被递归删除监控。
2018-04-17 18:58:22 +08:00
package gfsnotify
import (
"gitee.com/johng/gf/g/container/gmap"
2018-04-18 15:17:07 +08:00
"gitee.com/johng/gf/g/container/gqueue"
"gitee.com/johng/gf/g/encoding/ghash"
"gitee.com/johng/gf/g/os/gcache"
"gitee.com/johng/gf/third/github.com/fsnotify/fsnotify"
2018-04-17 18:58:22 +08:00
)
// 监听管理对象
type Watcher struct {
watcher *fsnotify.Watcher // 底层fsnotify对象
events *gqueue.Queue // 过滤后的事件通知,不会出现重复事件
closeChan chan struct{} // 关闭事件
callbacks *gmap.StringInterfaceMap // 监听的回调函数
cache *gcache.Cache // 缓存对象,用于事件重复过滤
2018-04-17 18:58:22 +08:00
}
// 监听事件对象
type Event struct {
event fsnotify.Event // 底层事件对象
Path string // 文件绝对路径
Op Op // 触发监听的文件操作
Watcher *Watcher // 事件对应的监听对象
2018-04-17 18:58:22 +08:00
}
// 按位进行识别的操作集合
type Op uint32
// 必须放到一个const分组里面
2018-04-17 18:58:22 +08:00
const (
CREATE Op = 1 << iota
WRITE
REMOVE
RENAME
CHMOD
)
const (
REPEAT_EVENT_FILTER_INTERVAL = 1 // (毫秒)重复事件过滤间隔
DEFAULT_WATCHER_COUNT = 8 // 默认创建的监控对象数量(使用哈希取模)
)
2018-04-17 18:58:22 +08:00
// 全局监听对象,方便应用端调用
var watchers = make([]*Watcher, DEFAULT_WATCHER_COUNT)
2018-04-18 15:17:07 +08:00
// 包初始化创建8个watcher对象用于包默认管理监听
func init() {
for i := 0; i < DEFAULT_WATCHER_COUNT; i++ {
if w, err := New(); err == nil {
watchers[i] = w
} else {
panic(err)
}
}
}
// 创建监听管理对象主要注意的是创建监听对象会占用系统的inotify句柄数量受到 fs.inotify.max_user_instances 的限制
2018-08-19 11:28:51 +08:00
func New() (*Watcher, error) {
2018-04-17 18:58:22 +08:00
if watch, err := fsnotify.NewWatcher(); err == nil {
w := &Watcher {
cache : gcache.New(),
watcher : watch,
events : gqueue.New(),
2018-09-19 09:47:50 +08:00
closeChan : make(chan struct{}),
callbacks : gmap.NewStringInterfaceMap(),
2018-04-17 18:58:22 +08:00
}
w.startWatchLoop()
2018-04-18 15:17:07 +08:00
w.startEventLoop()
2018-04-17 18:58:22 +08:00
return w, nil
} else {
return nil, err
}
}
// 添加对指定文件/目录的监听,并给定回调函数;如果给定的是一个目录,默认递归监控。
func Add(path string, callback func(event *Event), recursive...bool) error {
return getWatcherByPath(path).Add(path, callback, recursive...)
}
// 移除监听,默认递归删除。
func Remove(path string) error {
return getWatcherByPath(path).Remove(path)
}
// 根据path计算对应的watcher对象
func getWatcherByPath(path string) *Watcher {
return watchers[ghash.BKDRHash([]byte(path)) % DEFAULT_WATCHER_COUNT]
2018-04-18 09:16:08 +08:00
}