qinglong-go/utils/run.go

126 lines
2.7 KiB
Go
Raw Normal View History

2022-11-20 14:11:47 +00:00
package utils
import (
"context"
2023-02-03 04:43:37 +00:00
"fmt"
2022-11-20 14:11:47 +00:00
"io"
"os"
"os/exec"
"strings"
2023-09-04 06:02:25 +00:00
"github.com/huoxue1/go-utils/base/log"
"github.com/huoxue1/qinglong-go/service/config"
2022-11-20 14:11:47 +00:00
)
type Context struct {
process *os.Process
}
func RunTask(ctx context.Context, command string, env map[string]string, onStart func(ctx context.Context), onEnd func(ctx context.Context), logFile io.Writer) {
cmd := exec.Command(strings.Split(command, " ")[0], strings.Split(command, " ")[1:]...)
for s, s2 := range env {
cmd.Env = append(cmd.Env, s+"="+s2)
}
2023-02-03 04:43:37 +00:00
environ := os.Environ()
dir, _ := os.Getwd()
port := config.ListenPort()
cmd.Env = append(append(cmd.Env, environ...), "QL_DIR="+dir, fmt.Sprintf("QL_PORT=%d", port))
2022-11-20 14:11:47 +00:00
stdoutPipe, _ := cmd.StdoutPipe()
stderrPipe, _ := cmd.StderrPipe()
cmd.Dir = "./data/scripts/"
onStart(context.WithValue(ctx, "log", logFile))
ch := make(chan int, 1)
go func() {
err := cmd.Start()
if err != nil {
ch <- 1
return
}
go io.Copy(logFile, stderrPipe)
go io.Copy(logFile, stdoutPipe)
err = cmd.Wait()
if err != nil {
ch <- 1
return
}
ch <- 1
}()
cancel := ctx.Value("cancel").(chan int)
select {
case <-ch:
{
onEnd(context.WithValue(ctx, "log", logFile))
}
case <-cancel:
{
_ = cmd.Process.Kill()
onEnd(context.WithValue(context.Background(), "log", logFile))
}
}
}
2023-01-14 13:52:38 +00:00
type RunOption struct {
2023-02-03 04:43:37 +00:00
Ctx context.Context
2023-01-14 13:52:38 +00:00
Command string
Env map[string]string
OnStart func(ctx context.Context)
OnEnd func(ctx context.Context)
LogFile io.Writer
CmdDir string
}
func RunWithOption(ctx context.Context, option *RunOption) {
2023-02-03 04:43:37 +00:00
defer func() {
err := recover()
if err != nil {
log.Errorln("执行command出现异常")
log.Errorln(err)
}
}()
2023-01-14 13:52:38 +00:00
cmd := exec.Command(strings.Split(option.Command, " ")[0], strings.Split(option.Command, " ")[1:]...)
for s, s2 := range option.Env {
cmd.Env = append(cmd.Env, s+"="+s2)
}
environ := os.Environ()
2023-02-03 04:43:37 +00:00
dir, _ := os.Getwd()
port := config.ListenPort()
cmd.Env = append(append(cmd.Env, environ...), "QL_DIR="+dir, fmt.Sprintf("QL_PORT=%d", port))
2023-01-14 13:52:38 +00:00
stdoutPipe, _ := cmd.StdoutPipe()
stderrPipe, _ := cmd.StderrPipe()
cmd.Dir = option.CmdDir
option.OnStart(context.WithValue(ctx, "log", option.LogFile))
ch := make(chan int, 1)
go func() {
err := cmd.Start()
if err != nil {
ch <- 1
return
}
2023-09-05 11:35:54 +00:00
io.Copy(option.LogFile, stderrPipe)
io.Copy(option.LogFile, stdoutPipe)
2023-01-14 13:52:38 +00:00
err = cmd.Wait()
if err != nil {
ch <- 1
return
}
ch <- 1
}()
2023-09-04 06:02:25 +00:00
cancel, ok := ctx.Value("cancel").(chan int)
if ok {
cancel = make(chan int)
}
2023-01-14 13:52:38 +00:00
select {
case <-ch:
{
option.OnEnd(context.WithValue(ctx, "log", option.LogFile))
}
case <-cancel:
{
_ = cmd.Process.Kill()
option.OnEnd(context.WithValue(context.Background(), "log", option.LogFile))
}
}
}