自动初始化数据库功能后端部分完成

This commit is contained in:
pixel
2021-03-04 15:57:07 +08:00
parent 87f101a7bf
commit e3057c4bd9
26 changed files with 2 additions and 1090 deletions
-199
View File
@@ -1,199 +0,0 @@
package utils
import (
"bytes"
"context"
"fmt"
"io"
"os"
"os/exec"
"runtime"
"sync"
)
//@author: [songzhibin97](https://github.com/songzhibin97)
//@interface_name: RunTask
//@description: Task接口
type RunTask interface {
AddTask()
RunTask()
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@struct_name: T
//@description: Task任务
type T struct {
sync.Mutex
// 获取事件channel
ch chan struct{}
closeChan chan struct{}
// 记录process对象
p *os.Process
// 执行任务
f func(chan struct{}) error
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: NewT
//@description: T的实例化方法
//@return: *T
func NewT() *T {
return newT(nil)
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: newT
//@description:
//@param: f func(chan struct{}) error
//@return: *T
func newT(f func(chan struct{}) error) *T {
t := &T{
Mutex: sync.Mutex{},
ch: make(chan struct{}, 1),
closeChan: make(chan struct{}),
f: f,
}
if f == nil {
t.f = t.DefaultF
}
return t
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: *T
//@function: AddTask
//@description: 添加任务
func (t *T) AddTask() {
select {
case t.ch <- struct{}{}:
default:
// 代表已经有任务了
// 直接丢弃这次任务
}
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: *T
//@function: RunTask
//@description: 启动任务
func (t *T) RunTask() {
fmt.Println("进入")
// 这里做的make 是用于关闭上一个执行的任务
ch := make(chan struct{})
// 先run服务
go t.f(ch)
for {
_, ok := <-t.ch
if !ok {
return
}
ch <- struct{}{}
// 等待上一个关闭
<-t.closeChan
go t.f(ch)
}
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: t *T
//@function: DefaultF
//@description: 默认的StartFunction
//@param: ch chan struct{}
//@return: error
func (t *T) DefaultF(ch chan struct{}) error {
var buildCmd *exec.Cmd
var cmd *exec.Cmd
// 检测系统是否有编译环境
_, err := exec.LookPath("go")
if err != nil {
return err
}
// build
switch runtime.GOOS {
case "windows":
buildCmd = exec.Command("go", "build", "-o", "server.exe", "main.go")
default:
buildCmd = exec.Command("go", "build", "-o", "server", "main.go")
}
//cmd = exec.Command("go", "run", "main.go")
err = buildCmd.Run()
if err != nil {
return err
}
fmt.Println("build 执行完成")
// 执行
switch runtime.GOOS {
case "windows":
cmd = exec.Command("server.exe")
default:
cmd = exec.Command("./server")
}
// 开始执行任务
ctx, cancel := context.WithCancel(context.Background())
err = t.echo(cmd, ctx)
<-ch
// 回收资源
fmt.Println("pid:", t.p.Pid, "->Kill")
err = t.p.Kill()
cancel()
// 发送关闭完成信号
t.closeChan <- struct{}{}
return err
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: t *T
//@function: echo
//@description: 封装回显
//@param: cmd *exec.Cmd, ctx context.Context
//@return: error
func (t *T) echo(cmd *exec.Cmd, ctx context.Context) error {
var stdoutBuf bytes.Buffer
stdoutIn, _ := cmd.StdoutPipe()
var errStdout error
stdout := io.MultiWriter(os.Stdout, &stdoutBuf)
err := cmd.Start()
if err != nil {
return err
}
go func(ctx context.Context) {
_, errStdout = io.Copy(stdout, stdoutIn)
select {
case <-ctx.Done():
return
default:
}
}(ctx)
t.p = cmd.Process
fmt.Println("pid", t.p.Pid)
go func() {
_ = cmd.Wait()
if errStdout != nil {
fmt.Printf("failed to capture stdout or stderr\n")
}
fmt.Printf("%s\n", string(stdoutBuf.Bytes()))
select {
case <-ctx.Done():
//_ = os.Stdout.Close()
return
default:
}
}()
return nil
}
-174
View File
@@ -1,174 +0,0 @@
package utils
import (
"errors"
"fmt"
"github.com/fsnotify/fsnotify"
"io/ioutil"
"os"
"path/filepath"
)
//@author: [songzhibin97](https://github.com/songzhibin97)
//@struct_name: Watch
//@description: 监控对象
type Watch struct {
*fsnotify.Watcher
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: NewWatch
//@description: Watch的实例化方法
//@return: *Watch
func NewWatch() *Watch {
obj, _ := fsnotify.NewWatcher()
return &Watch{obj}
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: w *Watch
//@function: Watch
//@description: 监控对象
//@param: path string, t *T
//@return: error
func (w *Watch) Watch(path string, t *T) 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
}
// 判断事件
switch {
case even.Op&fsnotify.Create == fsnotify.Create:
//这里获取新创建文件的信息,如果是目录,则加入监控中
fmt.Println("创建文件 : ", even.Name)
//t.AddTask()
_ = w.Add(even.Name)
case even.Op&fsnotify.Write == fsnotify.Write:
fmt.Println("修改文件 : ", even.Name)
w.addTask(t, even.Name)
case even.Op&fsnotify.Remove == fsnotify.Remove || even.Op&fsnotify.Rename == fsnotify.Rename:
fmt.Println("删除或重命名文件 : ", even.Name)
_ = w.Remove(even.Name)
w.addTask(t, even.Name)
}
case err = <-w.Errors:
fmt.Println("even Error:", err)
c <- err
return
}
}
}()
return <-c
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: w *Watch
//@function: watchDir
//@description: 处理监控目录
//@param: path string
//@return: error
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() {
// 判断是否可监控的文件
if chickPower(fPath) {
err = w.watchFile(fPath)
if err != nil {
return err
}
}
} else {
err := w.watchDir(fPath)
if err != nil {
return err
}
}
}
return err
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: w *Watch
//@function: watchDir
//@description: 处理监控单文件
//@param: path string
//@return: error
func (w *Watch) watchFile(path string) error {
var err error
if chickPower(path) {
err = w.Add(path)
}
return err
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: chickPower
//@description: 判断是否在可控范围内
//@param: path string
//@return: error
func chickPower(name string) bool {
name = filepath.Ext(name)
return name == ".go" || name == ".yaml"
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: w *Watch
//@function: addTask
//@description: 偏函数 简化发送任务
//@param: path string
//@return: error
func (w *Watch) addTask(t *T, name string) {
if chickPower(name) {
fmt.Println("Add Task->>>>>>")
t.AddTask()
}
}