From 19c5eaa8191673e66c463eb80e29e3be57bf89c2 Mon Sep 17 00:00:00 2001 From: dengsgo Date: Sat, 29 Dec 2018 17:49:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E4=B8=A2=E5=BC=83=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + fileboy.go | 60 +++------------------------------- tasker.go | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 56 deletions(-) create mode 100644 tasker.go diff --git a/.gitignore b/.gitignore index 725e205..22cac34 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ fileboy fileboy.exe filegirl.yaml +build-* \ No newline at end of file diff --git a/fileboy.go b/fileboy.go index 02da576..fbfb29d 100644 --- a/fileboy.go +++ b/fileboy.go @@ -1,19 +1,15 @@ package main import ( - "bufio" "fmt" "gopkg.in/fsnotify/fsnotify.v1" "gopkg.in/yaml.v2" - "io" "io/ioutil" "log" "math/rand" "os" - "os/exec" "path" "strconv" - "sync" "time" ) @@ -28,9 +24,7 @@ var ( watcher *fsnotify.Watcher - cmd *exec.Cmd - - runLock sync.Mutex + tasker *Tasker ) type changeFile struct { @@ -67,14 +61,7 @@ func eventDispatcher(event fsnotify.Event) { case fsnotify.Create: case fsnotify.Write: log.Println("event write : ", event.Name) - if cmd != nil { - err := cmd.Process.Kill() - if err != nil { - log.Println("err: ", err) - } - log.Println("stop old process ") - } - go run(&changeFile{ + tasker.Put(&changeFile{ Name: relativePath(projectFolder, event.Name), Changed: time.Now().UnixNano(), Ext: ext, @@ -84,46 +71,6 @@ func eventDispatcher(event fsnotify.Event) { } } -func run(cf *changeFile) { - runLock.Lock() - defer runLock.Unlock() - for i := 0; i < len(cfg.Command.Exec); i++ { - carr := cmdParse2Array(cfg.Command.Exec[i], cf) - cmd = exec.Command(carr[0], carr[1:]...) - //cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: syscall.CREATE_UNICODE_ENVIRONMENT} - cmd.Stdin = os.Stdin - //cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Dir = projectFolder - cmd.Env = os.Environ() - stdout, err := cmd.StdoutPipe() - if err != nil { - log.Println("error=>", err.Error()) - return - } - cmd.Start() - reader := bufio.NewReader(stdout) - for { - line, err2 := reader.ReadString('\n') - if err2 != nil || io.EOF == err2 { - break - } - log.Print(line) - } - err = cmd.Wait() - if err != nil { - log.Println("cmd wait err ", err) - break - } - err = cmd.Process.Kill() - if err != nil { - log.Println("cmd cannot kill ", err) - } - } - - log.Println("end ") -} - func addWatcher() { log.Println("collecting directory information...") dirs := make([]string, 0) @@ -183,6 +130,7 @@ func initWatcher() { defer watcher.Close() done := make(chan bool) + tasker = newTasker(2000) go func() { for { select { @@ -229,7 +177,7 @@ func parseArgs() { return case "exec": parseConfig() - run(new(changeFile)) + newTasker(0).run(new(changeFile)) return case "version": fallthrough diff --git a/tasker.go b/tasker.go new file mode 100644 index 0000000..969dd16 --- /dev/null +++ b/tasker.go @@ -0,0 +1,95 @@ +package main + +import ( + "bufio" + "io" + "log" + "os" + "os/exec" + "sync" + "time" +) + +type Tasker struct { + lastTaskId int64 + delay int + cmd *exec.Cmd + putLock sync.Mutex + runLock sync.Mutex +} + +func newTasker(delay int) *Tasker { + return &Tasker{ + delay: delay, + } +} + +func (t *Tasker) Put(cf *changeFile) { + if t.delay < 1 { + go t.run(cf) + return + } + t.putLock.Lock() + defer t.putLock.Unlock() + t.lastTaskId = cf.Changed + go func() { + tc := time.Tick(time.Millisecond * time.Duration(t.delay)) + <-tc + if t.lastTaskId > cf.Changed { + return + } + t.preRun(cf) + }() +} + +func (t *Tasker) preRun(cf *changeFile) { + if t.cmd != nil { + err := t.cmd.Process.Kill() + if err != nil { + log.Println("err: ", err) + } + log.Println("stop old process ") + } + go t.run(cf) +} + +func (t *Tasker) run(cf *changeFile) { + 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(carr) + t.cmd = exec.Command(carr[0], carr[1:]...) + //cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: syscall.CREATE_UNICODE_ENVIRONMENT} + t.cmd.Stdin = os.Stdin + //cmd.Stdout = os.Stdout + t.cmd.Stderr = os.Stderr + t.cmd.Dir = projectFolder + t.cmd.Env = os.Environ() + stdout, err := t.cmd.StdoutPipe() + if err != nil { + log.Println("error=>", err.Error()) + return + } + _ = t.cmd.Start() + reader := bufio.NewReader(stdout) + for { + line, err2 := reader.ReadString('\n') + if err2 != nil || io.EOF == err2 { + break + } + log.Print(line) + } + err = t.cmd.Wait() + if err != nil { + log.Println("cmd wait err ", err) + break + } + err = t.cmd.Process.Kill() + if err != nil { + log.Println("cmd cannot kill ", err) + } + } + + log.Println("end ") +}