Merge pull request #334 from trheyi/v0.10.3-dev

[add] migrate watch
This commit is contained in:
Max 2023-04-01 11:44:01 +08:00 committed by GitHub
commit 63e6c35d42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 81 additions and 159 deletions

View file

@ -22,7 +22,7 @@ jobs:
- name: Get Version - name: Get Version
run: | run: |
echo VERSION=$(cat share/const.go |grep 'const VERSION' | awk '{print $4}' | sed "s/\"//g") >> $GITHUB_ENV echo VERSION=$(cat share/const.go |grep 'const VERSION' | awk '{print $4}' | sed "s/\"//g")-dev >> $GITHUB_ENV
- name: Check Version - name: Check Version
run: echo $VERSION run: echo $VERSION

View file

@ -6,7 +6,7 @@ on:
tags: tags:
description: "Version tags" description: "Version tags"
push: push:
branches: [main] branches: [v0.10.3-dev]
paths: paths:
- "share/const.go" - "share/const.go"
@ -108,6 +108,8 @@ jobs:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v2 uses: actions/checkout@v2
with:
ref: v0.10.3-dev
- name: Setup Go ${{ matrix.go }} - name: Setup Go ${{ matrix.go }}
uses: actions/setup-go@v3 uses: actions/setup-go@v3

View file

@ -6,7 +6,7 @@ on:
tags: tags:
description: "Version tags" description: "Version tags"
push: push:
branches: [main] branches: [v0.10.3-dev]
paths: paths:
- "share/const.go" - "share/const.go"
@ -105,6 +105,8 @@ jobs:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v2 uses: actions/checkout@v2
with:
ref: v0.10.3-dev
- name: Setup Go ${{ matrix.go }} - name: Setup Go ${{ matrix.go }}
uses: actions/setup-go@v3 uses: actions/setup-go@v3

View file

@ -4,9 +4,9 @@ on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
tags: tags:
description: "Comment" description: "Version"
push: push:
branches: [main] branches: [v0.10.3-dev]
env: env:
YAO_DEV: ${{ github.WORKSPACE }} YAO_DEV: ${{ github.WORKSPACE }}
@ -133,6 +133,8 @@ jobs:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v3 uses: actions/checkout@v3
with:
ref: v0.10.3-dev
- name: Start Redis - name: Start Redis
uses: supercharge/redis-github-action@1.4.0 uses: supercharge/redis-github-action@1.4.0

View file

@ -174,7 +174,7 @@ artifacts-linux: clean
mv dist/yao-*-* dist/release/ mv dist/yao-*-* dist/release/
chmod +x dist/release/yao-*-* chmod +x dist/release/yao-*-*
ls -l dist/release/ ls -l dist/release/
dist/release/yao-${VERSION}-linux-amd64 version dist/release/yao-${VERSION}-dev-linux-amd64 version
# Reset const # Reset const
# cp -f share/const.goe share/const.go # cp -f share/const.goe share/const.go
@ -224,7 +224,7 @@ artifacts-macos: clean
mv dist/yao-*-* dist/release/ mv dist/yao-*-* dist/release/
chmod +x dist/release/yao-*-* chmod +x dist/release/yao-*-*
ls -l dist/release/ ls -l dist/release/
dist/release/yao-${VERSION}-darwin-amd64 version dist/release/yao-${VERSION}-dev-darwin-amd64 version
# Reset const # Reset const
# cp -f share/const.goe share/const.go # cp -f share/const.goe share/const.go

View file

@ -1,5 +1,5 @@
<p align="center"> <p align="center">
<h1 align="center">YAO App Engine</h1> <h1 align="center">YAO App Engine ( v0.10.3 - dev ) </h1>
</p> </p>
<p align="center"> <p align="center">

View file

@ -129,13 +129,15 @@ var startCmd = &cobra.Command{
} }
// start watching srv, err := service.Start(config.Conf)
if mode == "development" && !startDisableWatching { defer func() {
// Watching service.Stop(srv)
fmt.Println(color.WhiteString("\n---------------------------------")) fmt.Println(color.GreenString(L("✨EXITED✨")))
fmt.Println(color.WhiteString(L("Watching"))) }()
fmt.Println(color.WhiteString("---------------------------------"))
// service.Watch(config.Conf) if err != nil {
fmt.Println(color.RedString(L("Fatal: %s"), err.Error()))
os.Exit(1)
} }
// print the messages under the production mode // print the messages under the production mode
@ -147,11 +149,15 @@ var startCmd = &cobra.Command{
printStores(true) printStores(true)
} }
srv, err := service.Start(config.Conf) // start watching
defer func() { watchDone := make(chan uint8, 1)
service.Stop(srv) if mode == "development" && !startDisableWatching {
fmt.Println(color.GreenString(L("✨EXITED✨"))) // Watching
}() fmt.Println(color.WhiteString("\n---------------------------------"))
fmt.Println(color.WhiteString(L("Watching")))
fmt.Println(color.WhiteString("---------------------------------"))
go service.Watch(srv, watchDone)
}
for { for {
select { select {
@ -170,6 +176,7 @@ var startCmd = &cobra.Command{
} }
case <-interrupt: case <-interrupt:
watchDone <- 1
return return
} }
} }

View file

@ -20,7 +20,7 @@ ARG ARCH
RUN groupadd -r yao && useradd -r -g yao yao && \ RUN groupadd -r yao && useradd -r -g yao yao && \
apt-get update && \ apt-get update && \
apt-get install -y curl sudo procps net-tools apt-get install -y curl sudo procps net-tools
RUN curl -fsSL "https://release-sv-1252011659.cos.na-siliconvalley.myqcloud.com/archives/yao-${VERSION}-linux-${ARCH}" > /usr/local/bin/yao && \ RUN curl -fsSL "https://release-sv-1252011659.cos.na-siliconvalley.myqcloud.com/archives/yao-${VERSION}-dev-linux-${ARCH}" > /usr/local/bin/yao && \
chmod +x /usr/local/bin/yao && \ chmod +x /usr/local/bin/yao && \
mkdir -p /data/app mkdir -p /data/app

View file

@ -18,7 +18,7 @@ FROM alpine:latest
ARG VERSION ARG VERSION
ARG ARCH ARG ARCH
RUN apk --no-cache add curl RUN apk --no-cache add curl
RUN curl -fsSL "https://release-sv-1252011659.cos.na-siliconvalley.myqcloud.com/archives/yao-${VERSION}-linux-${ARCH}" > /usr/local/bin/yao && \ RUN curl -fsSL "https://release-sv-1252011659.cos.na-siliconvalley.myqcloud.com/archives/yao-${VERSION}-dev-linux-${ARCH}" > /usr/local/bin/yao && \
chmod +x /usr/local/bin/yao chmod +x /usr/local/bin/yao
RUN mkdir -p /data/app RUN mkdir -p /data/app
VOLUME /data/app VOLUME /data/app

View file

@ -13,6 +13,8 @@ import (
"github.com/fatih/color" "github.com/fatih/color"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
"github.com/yaoapp/gou/application"
"github.com/yaoapp/gou/server/http"
"github.com/yaoapp/kun/log" "github.com/yaoapp/kun/log"
"github.com/yaoapp/yao/config" "github.com/yaoapp/yao/config"
"github.com/yaoapp/yao/engine" "github.com/yaoapp/yao/engine"
@ -27,12 +29,41 @@ var handlers = map[string]func(root string, file string, event string, cfg confi
} }
// Watch the application code change for hot update // Watch the application code change for hot update
func Watch(cfg config.Config) (err error) { func Watch(srv *http.Server, interrupt chan uint8) (err error) {
go func() { err = watchStart(cfg) }()
select { if application.App == nil {
case <-watchReady: return fmt.Errorf("Application is not initialized")
return nil
} }
return application.App.Watch(func(event, name string) {
if strings.Contains(event, "CHMOD") {
return
}
// Reload
err = engine.Reload(config.Conf)
if err != nil {
fmt.Println(color.RedString("[Watch] Reload: %s", err.Error()))
return
}
fmt.Println(color.GreenString("[Watch] Reload Completed"))
// Model
if strings.HasPrefix(name, "/models") {
fmt.Println(color.GreenString("[Watch] Model: %s changed (Please run yao migrate manually)", name))
}
// Restart
if strings.HasPrefix(name, "/apis") {
err = srv.Restart()
if err != nil {
fmt.Println(color.RedString("[Watch] Restart: %s", err.Error()))
return
}
fmt.Println(color.GreenString("[Watch] Restart Completed"))
}
}, interrupt)
} }
// StopWatch stop watching the code change // StopWatch stop watching the code change

View file

@ -1,153 +1,31 @@
package service package service
import ( import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing" "testing"
"time" "time"
"github.com/yaoapp/yao/config" "github.com/yaoapp/yao/config"
"github.com/yaoapp/yao/share" "github.com/yaoapp/yao/engine"
) )
func TestWatch(t *testing.T) { func TestWatch(t *testing.T) {
err := engine.Load(config.Conf)
share.DBConnect(config.Conf.DB)
err := Watch(config.Conf)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer StopWatch()
createDir(t) srv, err := Start(config.Conf)
renameDir(t)
createModel(t)
changeModel(t)
renameModel(t)
removeModel(t)
createModel(t)
removeDir(t)
}
func TestWatchReload(t *testing.T) {
go Start(config.Conf)
// defer Stop(func() {})
share.DBConnect(config.Conf.DB)
watchReload("", "", "", config.Conf)
}
func createDir(t *testing.T) {
root := config.Conf.Root
file := filepath.Join(root, "models", "watch", "test")
fmt.Println("CREATE-DIR", file)
err := os.MkdirAll(file, os.ModePerm)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
time.Sleep(1 * time.Second) defer Stop(srv)
}
func renameDir(t *testing.T) { done := make(chan uint8, 1)
root := config.Conf.Root go Watch(srv, done)
file := filepath.Join(root, "models", "watch", "test")
new := filepath.Join(root, "models", "watch", "test_new")
fmt.Println("RENAME-DIR", file)
err := os.Rename(file, new)
if err != nil {
t.Fatal(err)
}
time.Sleep(1 * time.Second)
}
func removeDir(t *testing.T) { select {
root := config.Conf.Root case <-time.After(200 * time.Millisecond):
file := filepath.Join(root, "models", "watch") done <- 1
fmt.Println("REMOVE-DIR", file) return
err := os.RemoveAll(file)
if err != nil {
t.Fatal(err)
} }
time.Sleep(1 * time.Second)
}
func createModel(t *testing.T) {
dsl := `
{
"name": "watch-test",
"table": {
"name": "watch_test",
"comment": "WatchTest",
"engine": "InnoDB"
},
"columns": [
{ "name": "id", "type": "ID" },
{ "label": "Name", "name": "name", "type": "string", "index": true }
],
"relations": {},
"option": { "timestamps": true, "soft_deletes": true }
}
`
root := config.Conf.Root
file := filepath.Join(root, "models", "watch", "test_new", "watch.mod.json")
fmt.Println("CREATE", file)
err := ioutil.WriteFile(file, []byte(dsl), 0644)
if err != nil {
t.Fatal(err)
}
time.Sleep(1 * time.Second)
}
func changeModel(t *testing.T) {
dsl := `
{
"name": "watch-test",
"table": {
"name": "watch_test",
"comment": "WatchTest",
"engine": "InnoDB"
},
"columns": [
{ "name": "id", "type": "ID" },
{ "label": "Name", "name": "name", "type": "string", "index": true },
{ "label": "Data", "name": "data", "type": "json", "nullable": true }
],
"relations": {},
"option": { "timestamps": true, "soft_deletes": true }
}
`
root := config.Conf.Root
file := filepath.Join(root, "models", "watch", "test_new", "watch.mod.json")
fmt.Println("CHANGE", file)
err := ioutil.WriteFile(file, []byte(dsl), 0644)
if err != nil {
t.Fatal(err)
}
time.Sleep(1 * time.Second)
}
func renameModel(t *testing.T) {
root := config.Conf.Root
file := filepath.Join(root, "models", "watch", "test_new", "watch.mod.json")
new := filepath.Join(root, "models", "watch", "test_new", "watch_new.mod.json")
fmt.Println("RENAME", new)
err := os.Rename(file, new)
if err != nil {
t.Fatal(err)
}
time.Sleep(1 * time.Second)
}
func removeModel(t *testing.T) {
root := config.Conf.Root
file := filepath.Join(root, "models", "watch", "test_new", "watch_new.mod.json")
fmt.Println("REMOVE", file)
err := os.Remove(file)
if err != nil {
t.Fatal(err)
}
time.Sleep(1 * time.Second)
} }