3 Commits
v1.0.0 ... main

Author SHA1 Message Date
moqsien
e6ea8e4fdd v1.0.3 2022-09-22 14:10:43 +08:00
moqsien
a2276e1a56 IProc 2022-09-22 13:59:01 +08:00
moqsien
7ba266b4f5 v1.0.1 2022-09-22 11:26:26 +08:00
3 changed files with 113 additions and 100 deletions

View File

@@ -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())
}
} }

View File

@@ -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
} }

View File

@@ -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}
} }