fileboy/taskman.go
2019-12-27 18:09:56 +08:00

89 lines
1.8 KiB
Go

package main
import (
"log"
"os"
"os/exec"
"sync"
"time"
)
type TaskMan struct {
lastTaskId int64
delay int
cmd *exec.Cmd
notifier *NetNotifier
putLock sync.Mutex
runLock sync.Mutex
}
func newTaskMan(delay int, callUrl string) *TaskMan {
return &TaskMan{
delay: delay,
notifier: newNetNotifier(callUrl),
}
}
func (t *TaskMan) Put(cf *changedFile) {
if t.delay < 1 {
t.preRun(cf)
return
}
t.putLock.Lock()
defer t.putLock.Unlock()
t.lastTaskId = cf.Changed
go func() {
<-time.After(time.Millisecond * time.Duration(t.delay))
if t.lastTaskId > cf.Changed {
return
}
t.preRun(cf)
}()
}
func (t *TaskMan) preRun(cf *changedFile) {
if t.cmd != nil && t.cmd.Process != nil {
log.Println("stop old process ")
if err := t.cmd.Process.Kill(); err != nil {
log.Println(PreWarn, "stopped err, reason:", err)
}
}
go t.run(cf)
go t.notifier.Put(cf)
}
func (t *TaskMan) run(cf *changedFile) {
t.runLock.Lock()
defer t.runLock.Unlock()
for i := 0; i < len(cfg.Command.Exec); i++ {
carr := cmdParse2Array(cfg.Command.Exec[i], cf)
log.Println("EXEC", carr)
t.cmd = exec.Command(carr[0], carr[1:]...)
//cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: syscall.CREATE_UNICODE_ENVIRONMENT}
t.cmd.Stdin = os.Stdin
t.cmd.Stdout = os.Stdout
t.cmd.Stderr = os.Stderr
t.cmd.Dir = projectFolder
t.cmd.Env = os.Environ()
err := t.cmd.Start()
if err != nil {
log.Println(PreError, "run command", carr, "error. ", err)
break
}
err = t.cmd.Wait()
if err != nil {
log.Println(PreWarn, "command exec failed:", carr, err)
break
}
if t.cmd.Process != nil {
err := t.cmd.Process.Kill()
log.Println(t.cmd.ProcessState)
if t.cmd.ProcessState != nil && !t.cmd.ProcessState.Exited() {
log.Println(PreError, "command cannot stop!", carr, err)
}
}
}
log.Println("EXEC end")
}