Hotreload

Hotreload1
This commit is contained in:
songzhibin97
2020-11-14 19:21:06 +08:00
parent bf6f469dad
commit 6536caed75
3 changed files with 248 additions and 0 deletions

83
server/utils/cmd_Task.go Normal file
View File

@@ -0,0 +1,83 @@
package utils
import (
"os"
"os/exec"
"strings"
"sync"
)
type RunTask interface {
AddTask()
RunTask()
}
// T: Task任务
type T struct {
sync.Mutex
// ch: 获取时间channel
ch chan struct{}
// 记录pid 用于kill
pid int
// 执行shell命令
exec.Cmd
}
// NewT: 实例化方法
func NewT(path string, args []string, environment ...[]string) *T {
env := os.Environ()
if len(environment) > 0 {
for k, v := range environment[0] {
env[k] = v
}
}
t := &T{
Mutex: sync.Mutex{},
ch: make(chan struct{}),
Cmd: exec.Cmd{
Path: path,
Args: []string{path},
Env: env,
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
ExtraFiles: make([]*os.File, 0),
},
pid: os.Getpid(),
}
t.Dir, _ = os.Getwd()
if len(args) > 0 {
// Exclude of current binary path.
start := 0
if strings.EqualFold(path, args[0]) {
start = 1
}
t.Args = append(t.Args, args[start:]...)
}
return t
}
func (t *T) AddTask() {
t.Lock()
defer t.Unlock()
if len(t.ch) == 1 {
// 代表已经有任务了
// 直接丢弃这次任务
return
}
t.ch <- struct{}{}
}
func (t *T) RunTask() {
for {
_, ok := <-t.ch
if !ok {
return
}
// todo 执行任务
}
}

118
server/utils/cmd_monitor.go Normal file
View File

@@ -0,0 +1,118 @@
package utils
import (
"errors"
"fmt"
"github.com/fsnotify/fsnotify"
"io/ioutil"
"os"
"path/filepath"
)
// Watch: 监控对象
type Watch struct {
*fsnotify.Watcher
}
func NewWatch() *Watch {
obj, _ := fsnotify.NewWatcher()
return &Watch{obj}
}
// Watch: 监控对象
func (w *Watch) Watch(path string) error {
// 先转化为绝对路径
path, err := filepath.Abs(path)
if err != nil {
return err
}
// 判断是单个文件还是目录文件
fileInfo, err := os.Stat(path)
if err != nil {
return err
}
// 判断是否是目录 添加监控
if fileInfo.IsDir() {
// dir
err = w.watchDir(path)
} else {
err = w.watchFile(path)
}
if err != nil {
return err
}
c := make(chan error)
// 启动监控
go func() {
for {
select {
case even, ok := <-w.Events:
if !ok {
// close
fmt.Println("Errors close")
c <- errors.New("errors close")
return
}
// 判断时间
fmt.Println("even", even)
switch {
// todo 待处理
case even.Op&fsnotify.Create == fsnotify.Create:
//这里获取新创建文件的信息,如果是目录,则加入监控中
fmt.Println("创建文件 : ", even.Name)
_ = w.Add(even.Name)
case even.Op&fsnotify.Write == fsnotify.Write:
fmt.Println("修改 : ", even.Name)
case even.Op&fsnotify.Remove == fsnotify.Remove:
fmt.Println("删除 : ", even.Name)
_ = w.Remove(even.Name)
case even.Op&fsnotify.Rename == fsnotify.Rename:
fmt.Println("重命名 : ", even.Name)
_ = w.Remove(even.Name)
}
case err = <-w.Errors:
c <- err
return
}
}
}()
return <-c
}
// watchDir: 处理监控目录
func (w *Watch) watchDir(path string) error {
// 先将自己添加到监控
err := w.Add(path)
if err != nil {
return err
}
fileSlice, err := ioutil.ReadDir(path)
if err != nil {
return err
}
for _, f := range fileSlice {
fPath := filepath.Join(path, f.Name())
if !f.IsDir() {
// todo 这里加一些条件筛选添加监控的内容
err = w.watchFile(fPath)
if err != nil {
return err
}
} else {
err := w.watchDir(fPath)
if err != nil {
return err
}
}
}
return err
}
// watchDir: 处理监控单文件
func (w *Watch) watchFile(path string) error {
return w.Add(path)
}