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
|
||||
|
||||
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() {
|
||||
manager := processes.NewProcManager()
|
||||
process, _ := manager.NewProcess("test",
|
||||
processes.ProcPath("/usr/bin/ls"),
|
||||
processes.ProcArgs([]string{"/usr"}),
|
||||
var ch = make(chan interface{}, 6)
|
||||
|
||||
var tree = gtree.NewRedBlackTree(gutil.ComparatorString, true)
|
||||
|
||||
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", ""),
|
||||
)
|
||||
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"
|
||||
)
|
||||
|
||||
type ProcManager struct {
|
||||
Container *gmap.StrAnyMap // 存放ProcessPlus进程对象的容器
|
||||
type IProc interface {
|
||||
StartProc(wait bool)
|
||||
StopProc(wait bool)
|
||||
GetProcessInfo() *Info
|
||||
Clone() (IProc, error)
|
||||
}
|
||||
|
||||
func NewProcManager() *ProcManager {
|
||||
return &ProcManager{
|
||||
Container: &gmap.StrAnyMap{},
|
||||
type Manager struct {
|
||||
*gmap.StrAnyMap
|
||||
}
|
||||
|
||||
func NewManager() *Manager {
|
||||
return &Manager{
|
||||
StrAnyMap: gmap.NewStrAnyMap(),
|
||||
}
|
||||
}
|
||||
|
||||
// NewProcess 创建新进程:path,可执行文件路径,一般os.Args[0]获取当前go程序可执行文件路径;name,进程名称
|
||||
func (that *ProcManager) NewProcess(name string, options ...Option) (p *ProcessPlus, err error) {
|
||||
func (that *Manager) NewProcess(name string, options ...Option) (p *ProcessPlus, err error) {
|
||||
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)
|
||||
}
|
||||
p.ProcManager = that
|
||||
@@ -33,96 +39,81 @@ func (that *ProcManager) NewProcess(name string, options ...Option) (p *ProcessP
|
||||
option(p)
|
||||
}
|
||||
}
|
||||
that.Add(name, p) // 新进程加入进程管理器中
|
||||
that.Add(name, p) // 添加进程
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Add 添加进程到Manager
|
||||
func (that *ProcManager) Add(name string, proc *ProcessPlus) {
|
||||
that.Container.Set(name, proc)
|
||||
logger.Info("添加进程:", name)
|
||||
// Add 添加进程,重复添加时会覆盖
|
||||
func (that *Manager) Add(name string, process IProc) {
|
||||
// 使用IProc接口作为参数,方便外部对ProcessPlus进行封装
|
||||
that.StrAnyMap.Set(name, process)
|
||||
}
|
||||
|
||||
// Remove 从Manager移除进程
|
||||
func (that *ProcManager) Remove(name string) *ProcessPlus {
|
||||
proc := that.Container.Remove(name)
|
||||
if proc == nil {
|
||||
return nil
|
||||
// Search 查找进程
|
||||
func (that *Manager) SearchProc(name string) (value IProc, found bool) {
|
||||
v, found := that.Search(name)
|
||||
if found {
|
||||
value = v.(IProc)
|
||||
}
|
||||
logger.Info("remove process:", name)
|
||||
return proc.(*ProcessPlus)
|
||||
return
|
||||
}
|
||||
|
||||
// Clear 清空容器
|
||||
func (that *ProcManager) Clear() {
|
||||
that.Container.Clear()
|
||||
// Remove 从列表移除进程
|
||||
func (that *Manager) Remove(name string) (value IProc) {
|
||||
that.StrAnyMap.Remove(name)
|
||||
return
|
||||
}
|
||||
|
||||
// ForEachProcess 迭代进程列表
|
||||
func (that *ProcManager) ForEachProcess(procFunc func(p *ProcessPlus)) {
|
||||
that.Container.Iterator(func(_ string, v interface{}) bool {
|
||||
procFunc(v.(*ProcessPlus))
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
// StopAllProcesses 关闭所有进程
|
||||
func (that *ProcManager) StopAllProcesses() {
|
||||
// StopAllProcs 停止所有进程
|
||||
func (that *Manager) StopAllProcs() {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
that.ForEachProcess(func(proc *ProcessPlus) {
|
||||
that.Iterator(func(_ string, value interface{}) bool {
|
||||
wg.Add(1)
|
||||
|
||||
go func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
proc.StopProc(true)
|
||||
go func(w *sync.WaitGroup) {
|
||||
defer w.Done()
|
||||
value.(IProc).StopProc(true)
|
||||
}(&wg)
|
||||
return true
|
||||
})
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// 获取所有进程列表
|
||||
func (that *ProcManager) getAllProcess() []*ProcessPlus {
|
||||
tmpProcList := make([]*ProcessPlus, 0)
|
||||
for _, proc := range that.Container.Map() {
|
||||
tmpProcList = append(tmpProcList, proc.(*ProcessPlus))
|
||||
}
|
||||
// GetAllProcs 获取所有进程的列表
|
||||
func (that *Manager) GetAllProcs() []IProc {
|
||||
tmpProcList := make([]IProc, 0)
|
||||
that.Iterator(func(_ string, value interface{}) bool {
|
||||
tmpProcList = append(tmpProcList, value.(IProc))
|
||||
return true
|
||||
})
|
||||
return tmpProcList
|
||||
}
|
||||
|
||||
// Find 根据进程名查询进程
|
||||
func (that *ProcManager) Find(name string) *ProcessPlus {
|
||||
proc, ok := that.Container.Search(name)
|
||||
if ok {
|
||||
return proc.(*ProcessPlus)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAllProcessInfo 获取所有进程信息
|
||||
func (that *ProcManager) GetAllProcessInfo() ([]*Info, error) {
|
||||
// GetAllProcsInfo 获取所有进程的信息列表
|
||||
func (that *Manager) GetAllProcsInfo() ([]*Info, error) {
|
||||
AllProcessInfo := make([]*Info, 0)
|
||||
that.ForEachProcess(func(proc *ProcessPlus) {
|
||||
procInfo := proc.GetProcessInfo()
|
||||
that.Iterator(func(_ string, value interface{}) bool {
|
||||
procInfo := value.(IProc).GetProcessInfo()
|
||||
AllProcessInfo = append(AllProcessInfo, procInfo)
|
||||
return true
|
||||
})
|
||||
return AllProcessInfo, nil
|
||||
}
|
||||
|
||||
// GracefulReload 平滑重启进程
|
||||
func (that *ProcManager) GracefulReload(name string, wait bool) (bool, error) {
|
||||
// GracefulReload 平滑重启
|
||||
func (that *Manager) GracefulReload(name string, wait bool) (bool, error) {
|
||||
logger.Infof("平滑重启进程[%s]", name)
|
||||
proc := that.Find(name)
|
||||
if proc == nil {
|
||||
p, ok := that.Search(name)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("没有找到要重启的进程[%s]", name)
|
||||
}
|
||||
|
||||
proc := p.(IProc)
|
||||
procClone, err := proc.Clone()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
procClone.StartProc(wait)
|
||||
proc.StopProc(wait)
|
||||
that.Container.Set(name, procClone)
|
||||
return true, nil
|
||||
that.Add(name, procClone)
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
21
procs.go
21
procs.go
@@ -20,14 +20,14 @@ import (
|
||||
type ProcessPlus struct {
|
||||
*exec.Cmd
|
||||
*ProcSettings
|
||||
ProcManager *ProcManager // 进程管理器
|
||||
Name string // 进程名称
|
||||
State ProcState // 进程的当前状态
|
||||
Starting bool // 正在启动的时候,该值为true
|
||||
StopByUser bool // 用户主动关闭的时候,该值为true
|
||||
RetryTimes *int32 // 启动重试的次数
|
||||
StartTime time.Time // 启动时间
|
||||
StopTime time.Time // 停止时间
|
||||
ProcManager *Manager // 进程管理器
|
||||
Name string // 进程名称
|
||||
State ProcState // 进程的当前状态
|
||||
Starting bool // 正在启动的时候,该值为true
|
||||
StopByUser bool // 用户主动关闭的时候,该值为true
|
||||
RetryTimes *int32 // 启动重试的次数
|
||||
StartTime time.Time // 启动时间
|
||||
StopTime time.Time // 停止时间
|
||||
|
||||
Lock sync.RWMutex
|
||||
Stdin io.WriteCloser
|
||||
@@ -81,7 +81,7 @@ func (that *ProcessPlus) Init() (err error) {
|
||||
}
|
||||
|
||||
// Clone 克隆进程
|
||||
func (that *ProcessPlus) Clone() (*ProcessPlus, error) {
|
||||
func (that *ProcessPlus) Clone() (IProc, error) {
|
||||
proc := NewProcess(that.Path, that.Name)
|
||||
proc.ProcManager = that.ProcManager
|
||||
|
||||
@@ -124,9 +124,8 @@ func (that *ProcessPlus) FailToStartProgram(reason string, finishCb func()) {
|
||||
|
||||
// 获取配置的退出code值列表
|
||||
func (that *ProcessPlus) GetExitCodes() []int {
|
||||
strExitCodes := that.ExitCodes
|
||||
if len(that.ExitCodes) > 0 {
|
||||
return strExitCodes
|
||||
return that.ExitCodes
|
||||
}
|
||||
return []int{0, 2}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user