增加 指令支持
This commit is contained in:
parent
9defc968ba
commit
4e0b9f54f6
12
fileboy.go
12
fileboy.go
@ -20,6 +20,9 @@ const (
|
|||||||
|
|
||||||
PreError = "ERROR:"
|
PreError = "ERROR:"
|
||||||
PreWarn = "Warn:"
|
PreWarn = "Warn:"
|
||||||
|
|
||||||
|
InstExecWhenStart = "exec-when-start"
|
||||||
|
InstShouldFinish = "should-finish"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -69,11 +72,15 @@ func parseConfig() {
|
|||||||
cfg.Monitor.IncludeDirsMap = map[string]bool{}
|
cfg.Monitor.IncludeDirsMap = map[string]bool{}
|
||||||
cfg.Monitor.ExceptDirsMap = map[string]bool{}
|
cfg.Monitor.ExceptDirsMap = map[string]bool{}
|
||||||
cfg.Monitor.IncludeDirsRec = map[string]bool{}
|
cfg.Monitor.IncludeDirsRec = map[string]bool{}
|
||||||
|
cfg.Command.InstructionMap = map[string]bool{}
|
||||||
// convert to map
|
// convert to map
|
||||||
for _, v := range cfg.Monitor.Types {
|
for _, v := range cfg.Monitor.Types {
|
||||||
cfg.Monitor.TypesMap[v] = true
|
cfg.Monitor.TypesMap[v] = true
|
||||||
}
|
}
|
||||||
log.Println(cfg)
|
for _, v := range cfg.Command.Instruction {
|
||||||
|
cfg.Command.InstructionMap[v] = true
|
||||||
|
}
|
||||||
|
log.Printf("%+v", cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func eventDispatcher(event fsnotify.Event) {
|
func eventDispatcher(event fsnotify.Event) {
|
||||||
@ -249,6 +256,9 @@ func parseArgs() {
|
|||||||
done := make(chan bool)
|
done := make(chan bool)
|
||||||
initWatcher()
|
initWatcher()
|
||||||
defer watcher.Close()
|
defer watcher.Close()
|
||||||
|
if keyInInstruction(InstExecWhenStart) {
|
||||||
|
taskMan.run(new(changedFile))
|
||||||
|
}
|
||||||
<-done
|
<-done
|
||||||
return
|
return
|
||||||
case len(os.Args) > 1:
|
case len(os.Args) > 1:
|
||||||
|
@ -18,8 +18,12 @@ type FileGirl struct {
|
|||||||
IncludeDirsRec map[string]bool `yaml:"-"`
|
IncludeDirsRec map[string]bool `yaml:"-"`
|
||||||
}
|
}
|
||||||
Command struct {
|
Command struct {
|
||||||
|
Instruction []string `yaml:"instruction"`
|
||||||
Exec []string `yaml:"exec"`
|
Exec []string `yaml:"exec"`
|
||||||
DelayMillSecond int `yaml:"delayMillSecond"`
|
DelayMillSecond int `yaml:"delayMillSecond"`
|
||||||
|
|
||||||
|
// convert to
|
||||||
|
InstructionMap map[string]bool `yaml:"-"`
|
||||||
}
|
}
|
||||||
Notifier struct {
|
Notifier struct {
|
||||||
CallUrl string `yaml:"callUrl"`
|
CallUrl string `yaml:"callUrl"`
|
||||||
|
14
raw.go
14
raw.go
@ -48,6 +48,20 @@ monitor:
|
|||||||
|
|
||||||
# 命令
|
# 命令
|
||||||
command:
|
command:
|
||||||
|
# 特殊指令 //TODO next release support
|
||||||
|
# 可以通过特殊的指令来控制 command 的行为,指令可以有多个
|
||||||
|
# exec-when-start fileboy启动就绪后,自动执行一次 'exec' 定义的命令
|
||||||
|
# should-finish 触发执行 'exec' 时(C),如果上一次的命令(L)未退出(还在执行),会等待 L 退出,直到有明确 exit code 才会开始执行本次命令。
|
||||||
|
# 在等待 L 退出时,又有新事件触发了命令执行(N),则 C 执行取消,只会保留最后一次的 N 执行
|
||||||
|
# ignore-stdout 执行 'exec' 产生的 stdout 会被丢弃
|
||||||
|
# ignore-warn fileboy 自身的 warn 信息会被丢弃
|
||||||
|
# ignore-info fileboy 自身的 info 信息会被丢弃
|
||||||
|
# ignore-exec-error 执行 'exec' 出错仍继续执行下面的命令而不退出
|
||||||
|
# limit-memory-256M 限制内存占用,超过 256M 'exec' 会被强制停止。格式 limit-memory-xxM
|
||||||
|
instruction:
|
||||||
|
#- should-finish
|
||||||
|
#- exec-when-start
|
||||||
|
|
||||||
# 监听的文件有更改会执行的命令
|
# 监听的文件有更改会执行的命令
|
||||||
# 可以有多条命令,会依次执行
|
# 可以有多条命令,会依次执行
|
||||||
# 如有多条命令,每条命令都会等待上一条命令执行完毕后才会执行
|
# 如有多条命令,每条命令都会等待上一条命令执行完毕后才会执行
|
||||||
|
54
taskman.go
54
taskman.go
@ -15,13 +15,35 @@ type TaskMan struct {
|
|||||||
notifier *NetNotifier
|
notifier *NetNotifier
|
||||||
putLock sync.Mutex
|
putLock sync.Mutex
|
||||||
runLock sync.Mutex
|
runLock sync.Mutex
|
||||||
|
|
||||||
|
waitChan chan bool
|
||||||
|
waitQueue []*changedFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTaskMan(delay int, callUrl string) *TaskMan {
|
func newTaskMan(delay int, callUrl string) *TaskMan {
|
||||||
return &TaskMan{
|
t := &TaskMan{
|
||||||
delay: delay,
|
delay: delay,
|
||||||
notifier: newNetNotifier(callUrl),
|
notifier: newNetNotifier(callUrl),
|
||||||
|
waitChan: make(chan bool, 1),
|
||||||
|
waitQueue: []*changedFile{},
|
||||||
}
|
}
|
||||||
|
if keyInInstruction(InstShouldFinish) {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
<-t.waitChan
|
||||||
|
if len(t.waitQueue) > 0 {
|
||||||
|
cf := t.waitQueue[len(t.waitQueue)-1]
|
||||||
|
if len(t.waitQueue) > 1 {
|
||||||
|
log.Println("Number of redundant tasks dropped:", len(t.waitQueue)-1)
|
||||||
|
}
|
||||||
|
t.waitQueue = []*changedFile{}
|
||||||
|
go t.preRun(cf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TaskMan) Put(cf *changedFile) {
|
func (t *TaskMan) Put(cf *changedFile) {
|
||||||
@ -37,14 +59,24 @@ func (t *TaskMan) Put(cf *changedFile) {
|
|||||||
if t.lastTaskId > cf.Changed {
|
if t.lastTaskId > cf.Changed {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.preRun(cf)
|
if keyInInstruction(InstShouldFinish) {
|
||||||
|
t.waitQueue = append(t.waitQueue, cf)
|
||||||
|
if t.cmd == nil {
|
||||||
|
t.waitChan <- true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("Waitting for the last task to finish")
|
||||||
|
log.Println("Number of waiting tasks:", len(t.waitQueue))
|
||||||
|
} else {
|
||||||
|
t.preRun(cf)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TaskMan) preRun(cf *changedFile) {
|
func (t *TaskMan) preRun(cf *changedFile) {
|
||||||
if t.cmd != nil && t.cmd.Process != nil {
|
if t.cmd != nil && t.cmd.Process != nil {
|
||||||
log.Println("stop old process ")
|
|
||||||
if err := t.cmd.Process.Kill(); err != nil {
|
if err := t.cmd.Process.Kill(); err != nil {
|
||||||
|
log.Println("stop old process ")
|
||||||
log.Println(PreWarn, "stopped err, reason:", err)
|
log.Println(PreWarn, "stopped err, reason:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,6 +84,13 @@ func (t *TaskMan) preRun(cf *changedFile) {
|
|||||||
go t.notifier.Put(cf)
|
go t.notifier.Put(cf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TaskMan) waitFinish() {
|
||||||
|
log.Println("prostate", t.cmd.Process.Pid)
|
||||||
|
if t.cmd.ProcessState != nil && !t.cmd.ProcessState.Exited() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TaskMan) run(cf *changedFile) {
|
func (t *TaskMan) run(cf *changedFile) {
|
||||||
t.runLock.Lock()
|
t.runLock.Lock()
|
||||||
defer t.runLock.Unlock()
|
defer t.runLock.Unlock()
|
||||||
@ -83,6 +122,9 @@ func (t *TaskMan) run(cf *changedFile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if keyInInstruction(InstShouldFinish) {
|
||||||
|
t.cmd = nil
|
||||||
|
t.waitChan <- true
|
||||||
|
}
|
||||||
log.Println("EXEC end")
|
log.Println("EXEC end")
|
||||||
}
|
}
|
||||||
|
5
util.go
5
util.go
@ -13,6 +13,11 @@ func keyInMonitorTypesMap(k string, cfg *FileGirl) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func keyInInstruction(k string) bool {
|
||||||
|
_, ok := cfg.Command.InstructionMap[k]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
func cmdParse2Array(s string, cf *changedFile) []string {
|
func cmdParse2Array(s string, cf *changedFile) []string {
|
||||||
a := strings.Split(s, " ")
|
a := strings.Split(s, " ")
|
||||||
r := make([]string, 0)
|
r := make([]string, 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user