+ 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"
|
"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",
|
"path": "/info/:id",
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ type Config struct {
|
||||||
// XiangConfig 象传应用引擎配置
|
// XiangConfig 象传应用引擎配置
|
||||||
type XiangConfig struct {
|
type XiangConfig struct {
|
||||||
Mode string `json:"mode,omitempty" env:"XIANG_MODE" envDefault:"release"` // 象传引擎模式 debug/release/test
|
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"` // 引擎文件目录
|
Path string `json:"path,omitempty" env:"XIANG_PATH" envDefault:"bin://xiang"` // 引擎文件目录
|
||||||
Root string `json:"root,omitempty" env:"XIANG_ROOT" envDefault:"fs://."` // 应用文件目录
|
Root string `json:"root,omitempty" env:"XIANG_ROOT" envDefault:"fs://."` // 应用文件目录
|
||||||
RootAPI string `json:"root_api,omitempty" env:"XIANG_ROOT_API"` // 应用API文件目录
|
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/caarlos0/env/v6 v6.7.1 // indirect
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||||
github.com/elazarl/go-bindata-assetfs v1.0.1 // 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/gin-gonic/gin v1.7.4 // indirect
|
||||||
github.com/joho/godotenv v1.3.0 // indirect
|
github.com/joho/godotenv v1.3.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // 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 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
|
||||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
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.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/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 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
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) {
|
request := func() (maps.MapStr, error) {
|
||||||
time.Sleep(time.Microsecond * 1000)
|
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)
|
// utils.Dump(url)
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,17 @@
|
||||||
{
|
{
|
||||||
"path": "/info/:id",
|
"path": "/info/:id",
|
||||||
"method": "GET",
|
"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",
|
"process": "models.user.Find",
|
||||||
"in": ["$param.id", ":params"],
|
"in": ["$param.id", ":params"],
|
||||||
"out": {
|
"out": {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue