mirror of
https://github.com/moqsien/processes.git
synced 2025-12-24 12:27:54 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6ea8e4fdd | ||
|
|
a2276e1a56 | ||
|
|
7ba266b4f5 |
@@ -1,34 +1,57 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/moqsien/processes"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gogf/gf/container/gtree"
|
||||||
|
"github.com/gogf/gf/util/gutil"
|
||||||
|
"github.com/moqsien/processes"
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
运行结果示例:
|
运行结果示例
|
||||||
|
|
||||||
2022-09-06 20:41:21.428 [INFO] 添加进程: test
|
|
||||||
2022-09-06 20:41:21.428 [INFO] 尝试启动程序[test]
|
|
||||||
2022-09-06 20:41:21.429 [DEBU] 进程正在运行[test]等待退出
|
|
||||||
bin
|
|
||||||
games
|
|
||||||
include
|
|
||||||
lib
|
|
||||||
lib32
|
|
||||||
lib64
|
|
||||||
libexec
|
|
||||||
libx32
|
|
||||||
local
|
|
||||||
sbin
|
|
||||||
share
|
|
||||||
src
|
|
||||||
2022-09-06 20:41:21.430 [INFO] 程序[test]已经结束运行,退出码为:exit status 0
|
|
||||||
*/
|
*/
|
||||||
|
var manager = processes.NewManager()
|
||||||
|
|
||||||
func main() {
|
var ch = make(chan interface{}, 6)
|
||||||
manager := processes.NewProcManager()
|
|
||||||
process, _ := manager.NewProcess("test",
|
var tree = gtree.NewRedBlackTree(gutil.ComparatorString, true)
|
||||||
processes.ProcPath("/usr/bin/ls"),
|
|
||||||
processes.ProcArgs([]string{"/usr"}),
|
func test(key interface{}, _ interface{}) bool {
|
||||||
|
name, _ := key.(string)
|
||||||
|
process, _ := manager.NewProcess(name,
|
||||||
|
processes.ProcPath(os.Args[0]),
|
||||||
|
processes.ProcArgs([]string{name}),
|
||||||
processes.ProcStdoutLog("/dev/stdout", ""),
|
processes.ProcStdoutLog("/dev/stdout", ""),
|
||||||
)
|
)
|
||||||
process.StartProc(true)
|
process.StartProc(true)
|
||||||
|
manager.Add(name, process)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func t(key string) {
|
||||||
|
for {
|
||||||
|
fmt.Println(">>>process: ", key)
|
||||||
|
time.Sleep(time.Duration(2) * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
args := os.Args[1:]
|
||||||
|
if len(args) == 0 {
|
||||||
|
tree.Set("a", 1)
|
||||||
|
tree.Set("b", 2)
|
||||||
|
tree.Set("c", 3)
|
||||||
|
tree.Set("d", 4)
|
||||||
|
tree.IteratorAsc(test)
|
||||||
|
} else if len(args) == 1 {
|
||||||
|
fmt.Println(args)
|
||||||
|
t(args[0])
|
||||||
|
}
|
||||||
|
p, found := manager.SearchProc("a")
|
||||||
|
if found {
|
||||||
|
fmt.Println(p.GetProcessInfo())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
121
proc_manager.go
121
proc_manager.go
@@ -10,20 +10,26 @@ import (
|
|||||||
"github.com/moqsien/processes/logger"
|
"github.com/moqsien/processes/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProcManager struct {
|
type IProc interface {
|
||||||
Container *gmap.StrAnyMap // 存放ProcessPlus进程对象的容器
|
StartProc(wait bool)
|
||||||
|
StopProc(wait bool)
|
||||||
|
GetProcessInfo() *Info
|
||||||
|
Clone() (IProc, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProcManager() *ProcManager {
|
type Manager struct {
|
||||||
return &ProcManager{
|
*gmap.StrAnyMap
|
||||||
Container: &gmap.StrAnyMap{},
|
}
|
||||||
|
|
||||||
|
func NewManager() *Manager {
|
||||||
|
return &Manager{
|
||||||
|
StrAnyMap: gmap.NewStrAnyMap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProcess 创建新进程:path,可执行文件路径,一般os.Args[0]获取当前go程序可执行文件路径;name,进程名称
|
func (that *Manager) NewProcess(name string, options ...Option) (p *ProcessPlus, err error) {
|
||||||
func (that *ProcManager) NewProcess(name string, options ...Option) (p *ProcessPlus, err error) {
|
|
||||||
p = NewProcess(os.Args[0], name)
|
p = NewProcess(os.Args[0], name)
|
||||||
if _, found := that.Container.Search(p.Name); found {
|
if _, found := that.Search(p.Name); found {
|
||||||
return nil, gerror.Newf("进程[%s]已存在", p.Name)
|
return nil, gerror.Newf("进程[%s]已存在", p.Name)
|
||||||
}
|
}
|
||||||
p.ProcManager = that
|
p.ProcManager = that
|
||||||
@@ -33,96 +39,81 @@ func (that *ProcManager) NewProcess(name string, options ...Option) (p *ProcessP
|
|||||||
option(p)
|
option(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
that.Add(name, p) // 新进程加入进程管理器中
|
that.Add(name, p) // 添加进程
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add 添加进程到Manager
|
// Add 添加进程,重复添加时会覆盖
|
||||||
func (that *ProcManager) Add(name string, proc *ProcessPlus) {
|
func (that *Manager) Add(name string, process IProc) {
|
||||||
that.Container.Set(name, proc)
|
// 使用IProc接口作为参数,方便外部对ProcessPlus进行封装
|
||||||
logger.Info("添加进程:", name)
|
that.StrAnyMap.Set(name, process)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove 从Manager移除进程
|
// Search 查找进程
|
||||||
func (that *ProcManager) Remove(name string) *ProcessPlus {
|
func (that *Manager) SearchProc(name string) (value IProc, found bool) {
|
||||||
proc := that.Container.Remove(name)
|
v, found := that.Search(name)
|
||||||
if proc == nil {
|
if found {
|
||||||
return nil
|
value = v.(IProc)
|
||||||
}
|
}
|
||||||
logger.Info("remove process:", name)
|
return
|
||||||
return proc.(*ProcessPlus)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear 清空容器
|
// Remove 从列表移除进程
|
||||||
func (that *ProcManager) Clear() {
|
func (that *Manager) Remove(name string) (value IProc) {
|
||||||
that.Container.Clear()
|
that.StrAnyMap.Remove(name)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachProcess 迭代进程列表
|
// StopAllProcs 停止所有进程
|
||||||
func (that *ProcManager) ForEachProcess(procFunc func(p *ProcessPlus)) {
|
func (that *Manager) StopAllProcs() {
|
||||||
that.Container.Iterator(func(_ string, v interface{}) bool {
|
|
||||||
procFunc(v.(*ProcessPlus))
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopAllProcesses 关闭所有进程
|
|
||||||
func (that *ProcManager) StopAllProcesses() {
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
that.Iterator(func(_ string, value interface{}) bool {
|
||||||
that.ForEachProcess(func(proc *ProcessPlus) {
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
go func(w *sync.WaitGroup) {
|
||||||
go func(wg *sync.WaitGroup) {
|
defer w.Done()
|
||||||
defer wg.Done()
|
value.(IProc).StopProc(true)
|
||||||
|
|
||||||
proc.StopProc(true)
|
|
||||||
}(&wg)
|
}(&wg)
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有进程列表
|
// GetAllProcs 获取所有进程的列表
|
||||||
func (that *ProcManager) getAllProcess() []*ProcessPlus {
|
func (that *Manager) GetAllProcs() []IProc {
|
||||||
tmpProcList := make([]*ProcessPlus, 0)
|
tmpProcList := make([]IProc, 0)
|
||||||
for _, proc := range that.Container.Map() {
|
that.Iterator(func(_ string, value interface{}) bool {
|
||||||
tmpProcList = append(tmpProcList, proc.(*ProcessPlus))
|
tmpProcList = append(tmpProcList, value.(IProc))
|
||||||
}
|
return true
|
||||||
|
})
|
||||||
return tmpProcList
|
return tmpProcList
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find 根据进程名查询进程
|
// GetAllProcsInfo 获取所有进程的信息列表
|
||||||
func (that *ProcManager) Find(name string) *ProcessPlus {
|
func (that *Manager) GetAllProcsInfo() ([]*Info, error) {
|
||||||
proc, ok := that.Container.Search(name)
|
|
||||||
if ok {
|
|
||||||
return proc.(*ProcessPlus)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllProcessInfo 获取所有进程信息
|
|
||||||
func (that *ProcManager) GetAllProcessInfo() ([]*Info, error) {
|
|
||||||
AllProcessInfo := make([]*Info, 0)
|
AllProcessInfo := make([]*Info, 0)
|
||||||
that.ForEachProcess(func(proc *ProcessPlus) {
|
that.Iterator(func(_ string, value interface{}) bool {
|
||||||
procInfo := proc.GetProcessInfo()
|
procInfo := value.(IProc).GetProcessInfo()
|
||||||
AllProcessInfo = append(AllProcessInfo, procInfo)
|
AllProcessInfo = append(AllProcessInfo, procInfo)
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
return AllProcessInfo, nil
|
return AllProcessInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GracefulReload 平滑重启进程
|
// GracefulReload 平滑重启
|
||||||
func (that *ProcManager) GracefulReload(name string, wait bool) (bool, error) {
|
func (that *Manager) GracefulReload(name string, wait bool) (bool, error) {
|
||||||
logger.Infof("平滑重启进程[%s]", name)
|
logger.Infof("平滑重启进程[%s]", name)
|
||||||
proc := that.Find(name)
|
p, ok := that.Search(name)
|
||||||
if proc == nil {
|
if !ok {
|
||||||
return false, fmt.Errorf("没有找到要重启的进程[%s]", name)
|
return false, fmt.Errorf("没有找到要重启的进程[%s]", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc := p.(IProc)
|
||||||
procClone, err := proc.Clone()
|
procClone, err := proc.Clone()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
procClone.StartProc(wait)
|
procClone.StartProc(wait)
|
||||||
proc.StopProc(wait)
|
proc.StopProc(wait)
|
||||||
that.Container.Set(name, procClone)
|
that.Add(name, procClone)
|
||||||
return true, nil
|
return ok, nil
|
||||||
}
|
}
|
||||||
|
|||||||
21
procs.go
21
procs.go
@@ -20,14 +20,14 @@ import (
|
|||||||
type ProcessPlus struct {
|
type ProcessPlus struct {
|
||||||
*exec.Cmd
|
*exec.Cmd
|
||||||
*ProcSettings
|
*ProcSettings
|
||||||
ProcManager *ProcManager // 进程管理器
|
ProcManager *Manager // 进程管理器
|
||||||
Name string // 进程名称
|
Name string // 进程名称
|
||||||
State ProcState // 进程的当前状态
|
State ProcState // 进程的当前状态
|
||||||
Starting bool // 正在启动的时候,该值为true
|
Starting bool // 正在启动的时候,该值为true
|
||||||
StopByUser bool // 用户主动关闭的时候,该值为true
|
StopByUser bool // 用户主动关闭的时候,该值为true
|
||||||
RetryTimes *int32 // 启动重试的次数
|
RetryTimes *int32 // 启动重试的次数
|
||||||
StartTime time.Time // 启动时间
|
StartTime time.Time // 启动时间
|
||||||
StopTime time.Time // 停止时间
|
StopTime time.Time // 停止时间
|
||||||
|
|
||||||
Lock sync.RWMutex
|
Lock sync.RWMutex
|
||||||
Stdin io.WriteCloser
|
Stdin io.WriteCloser
|
||||||
@@ -81,7 +81,7 @@ func (that *ProcessPlus) Init() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clone 克隆进程
|
// Clone 克隆进程
|
||||||
func (that *ProcessPlus) Clone() (*ProcessPlus, error) {
|
func (that *ProcessPlus) Clone() (IProc, error) {
|
||||||
proc := NewProcess(that.Path, that.Name)
|
proc := NewProcess(that.Path, that.Name)
|
||||||
proc.ProcManager = that.ProcManager
|
proc.ProcManager = that.ProcManager
|
||||||
|
|
||||||
@@ -124,9 +124,8 @@ func (that *ProcessPlus) FailToStartProgram(reason string, finishCb func()) {
|
|||||||
|
|
||||||
// 获取配置的退出code值列表
|
// 获取配置的退出code值列表
|
||||||
func (that *ProcessPlus) GetExitCodes() []int {
|
func (that *ProcessPlus) GetExitCodes() []int {
|
||||||
strExitCodes := that.ExitCodes
|
|
||||||
if len(that.ExitCodes) > 0 {
|
if len(that.ExitCodes) > 0 {
|
||||||
return strExitCodes
|
return that.ExitCodes
|
||||||
}
|
}
|
||||||
return []int{0, 2}
|
return []int{0, 2}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user