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

View File

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

View File

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