+ Watch
This commit is contained in:
parent
d5a9f7a54d
commit
8f4110646d
8 changed files with 150 additions and 2 deletions
|
|
@ -16,6 +16,17 @@
|
|||
"type": "application/json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/find/:id",
|
||||
"method": "GET",
|
||||
"guard": "-",
|
||||
"process": "models.user.Find",
|
||||
"in": ["$param.id", ":params"],
|
||||
"out": {
|
||||
"status": 200,
|
||||
"type": "application/json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/info/:id",
|
||||
"method": "GET",
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ type Config struct {
|
|||
// XiangConfig 象传应用引擎配置
|
||||
type XiangConfig struct {
|
||||
Mode string `json:"mode,omitempty" env:"XIANG_MODE" envDefault:"release"` // 象传引擎模式 debug/release/test
|
||||
Source string `json:"source,omitempty" env:"XIANG_SOURCE" envDefault:"fs://."` // 源码路径(用于调试时载入数据)
|
||||
Source string `json:"source,omitempty" env:"XIANG_SOURCE" envDefault:"fs://."` // 源码路径(用于单元测试载入数据)
|
||||
Path string `json:"path,omitempty" env:"XIANG_PATH" envDefault:"bin://xiang"` // 引擎文件目录
|
||||
Root string `json:"root,omitempty" env:"XIANG_ROOT" envDefault:"fs://."` // 应用文件目录
|
||||
RootAPI string `json:"root_api,omitempty" env:"XIANG_ROOT_API"` // 应用API文件目录
|
||||
|
|
|
|||
102
global/watch.go
Normal file
102
global/watch.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
package global
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
)
|
||||
|
||||
var watchDone = []chan bool{}
|
||||
var watchOp = map[fsnotify.Op]string{
|
||||
fsnotify.Create: "create",
|
||||
fsnotify.Write: "write",
|
||||
fsnotify.Remove: "remove",
|
||||
fsnotify.Rename: "rename",
|
||||
fsnotify.Chmod: "chmod",
|
||||
}
|
||||
|
||||
// Watch 监听目录
|
||||
func Watch(root string, cb func(op string, file string)) {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
watchDone = append(watchDone, make(chan bool))
|
||||
last := len(watchDone) - 1
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-watcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// 监听子目录
|
||||
if event.Op == fsnotify.Create {
|
||||
file, err := os.Open(event.Name)
|
||||
if err == nil {
|
||||
fi, err := file.Stat()
|
||||
file.Close()
|
||||
if err == nil && fi.IsDir() {
|
||||
Watch(event.Name, cb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cb(watchOp[event.Op], event.Name)
|
||||
|
||||
case err, ok := <-watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Println("error:", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
err = watcher.Add(root)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("开始监听目录:", root)
|
||||
|
||||
// 监听子目录
|
||||
filepath.Walk(root, func(subfolder string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
exception.Err(err, 500).Throw()
|
||||
return err
|
||||
}
|
||||
|
||||
if subfolder == root {
|
||||
return nil
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
go Watch(subfolder, cb)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
select {
|
||||
case v := <-watchDone[last]:
|
||||
log.Println("停止监听目录:", root)
|
||||
if v == true {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StopWatch 停止监听
|
||||
func StopWatch() {
|
||||
for i := range watchDone {
|
||||
log.Println("发送停止信号:", i)
|
||||
watchDone[i] <- true
|
||||
}
|
||||
watchDone = []chan bool{}
|
||||
}
|
||||
21
global/watch_test.go
Normal file
21
global/watch_test.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package global
|
||||
|
||||
import (
|
||||
"log"
|
||||
"path"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestWatchAddNew(t *testing.T) {
|
||||
root := path.Join(Conf.Source, "/app")
|
||||
assert.NotPanics(t, func() {
|
||||
go Watch(root, func(op string, file string) {
|
||||
log.Println(op, file)
|
||||
})
|
||||
time.Sleep(time.Second * 2)
|
||||
defer StopWatch()
|
||||
})
|
||||
}
|
||||
1
go.mod
1
go.mod
|
|
@ -6,6 +6,7 @@ require (
|
|||
github.com/caarlos0/env/v6 v6.7.1 // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/gin-gonic/gin v1.7.4 // indirect
|
||||
github.com/joho/godotenv v1.3.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -86,6 +86,8 @@ github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGE
|
|||
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
|
||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func TestCommandStart(t *testing.T) {
|
|||
// 发送请求
|
||||
request := func() (maps.MapStr, error) {
|
||||
time.Sleep(time.Microsecond * 1000)
|
||||
url := fmt.Sprintf("http://%s:%d/api/user/info/1?select=id,name", "local.iqka.com", global.Conf.Service.Port)
|
||||
url := fmt.Sprintf("http://%s:%d/api/user/find/1?select=id,name", "local.iqka.com", global.Conf.Service.Port)
|
||||
// utils.Dump(url)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,17 @@
|
|||
{
|
||||
"path": "/info/:id",
|
||||
"method": "GET",
|
||||
"guard": "-",
|
||||
"process": "models.user.Find",
|
||||
"in": ["$param.id", ":params"],
|
||||
"out": {
|
||||
"status": 200,
|
||||
"type": "application/json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/find/:id",
|
||||
"method": "GET",
|
||||
"process": "models.user.Find",
|
||||
"in": ["$param.id", ":params"],
|
||||
"out": {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue