-
Notifications
You must be signed in to change notification settings - Fork 63
/
process_manager.go
99 lines (88 loc) · 2.03 KB
/
process_manager.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package cron_task
import (
"encoding/base64"
"encoding/json"
"errors"
"io"
"os/exec"
"sync"
"github.com/hootrhino/rulex/component/rulex_api_server/model"
"github.com/hootrhino/rulex/glogger"
)
// ProcessManager
type ProcessManager struct {
runningProcess sync.Map
}
func NewProcessManager() *ProcessManager {
manager := ProcessManager{
runningProcess: sync.Map{},
}
return &manager
}
func (pm *ProcessManager) RunProcess(file io.Writer, task model.MCronTask) error {
// 0. arguments
// 1. working directory
// 2. environment
var command *exec.Cmd
args := make([]string, 0)
script, err := base64.StdEncoding.DecodeString(task.Script)
if err != nil {
glogger.GLogger.Error("parse script failed", err)
return err
}
if task.TaskType == CRON_TASK_TYPE_LINUX_SHELL {
args = append(args, "-c")
args = append(args, string(script))
args = append(args, "bash") // 占据$0位置
if task.Args != nil {
args = append(args, *task.Args) // 占据$1位置,此时$@与$1相同
}
} else {
return errors.New("unknown taskType")
}
command = exec.Command(task.Command, args...)
command.SysProcAttr = GetSysProcAttr()
command.Stderr = file
command.Stdout = file
command.Dir = task.WorkDir
envSlice := make([]string, 0)
err = json.Unmarshal([]byte(task.Env), &envSlice)
if err != nil {
return err
}
command.Env = envSlice
if err = command.Start(); err != nil {
return err
}
pm.runningProcess.Store(task.ID, command)
defer pm.runningProcess.Delete(task.ID)
err = command.Wait()
if err != nil {
return err
}
return nil
}
func (pm *ProcessManager) KillProcess(id string) error {
value, ok := pm.runningProcess.Load(id)
if !ok {
// not exist, return success
return nil
}
cmd := value.(*exec.Cmd)
err := KillProcess(cmd)
if err != nil {
return err
}
return nil
}
func (pm *ProcessManager) ListProcess() map[string]*exec.Cmd {
m := make(map[string]*exec.Cmd)
f := func(key, value any) bool {
k := key.(string)
cmd := value.(*exec.Cmd)
m[k] = cmd
return true
}
pm.runningProcess.Range(f)
return m
}