diff --git a/examples/ecosystem.json b/examples/ecosystem.json index a5cc23e..872ed12 100644 --- a/examples/ecosystem.json +++ b/examples/ecosystem.json @@ -5,7 +5,8 @@ "autorestart": false, "cwd": "./examples", "scripts": ["logs_date"], - "executable_path": "python3" + "executable_path": "python3", + "cron_restart": "* * * * *" }, { "name": "celery-worker", diff --git a/grpc/server/add_process.go b/grpc/server/add_process.go index c736209..c22ab70 100644 --- a/grpc/server/add_process.go +++ b/grpc/server/add_process.go @@ -4,7 +4,6 @@ import ( "context" "time" - "github.com/aptible/supercronic/cronexpr" pb "github.com/dunstorm/pm2-go/proto" "github.com/dunstorm/pm2-go/utils" "google.golang.org/grpc/status" @@ -36,14 +35,9 @@ func (api *Handler) AddProcess(ctx context.Context, in *pb.AddProcessRequest) (* ParentPid: 1, }, } - - if in.CronRestart != "" { - expr, err := cronexpr.Parse(in.CronRestart) - if err != nil { - return nil, status.Errorf(400, "invalid cron expression: %v", err) - } - newProcess.CronRestart = in.CronRestart - newProcess.NextStartAt = timestamppb.New(expr.Next(time.Now())) + err := newProcess.UpdateNextStartAt() + if err != nil { + return nil, err } process, running := utils.GetProcess(newProcess.Pid) diff --git a/grpc/server/start_process.go b/grpc/server/start_process.go index 74d56a6..ed20eda 100644 --- a/grpc/server/start_process.go +++ b/grpc/server/start_process.go @@ -26,6 +26,12 @@ func (api *Handler) StartProcess(ctx context.Context, in *pb.StartProcessRequest process.AutoRestart = in.AutoRestart process.Cwd = in.Cwd process.Pid = in.Pid + process.CronRestart = in.CronRestart + process.ProcStatus.ParentPid = 1 + err := process.UpdateNextStartAt() + if err != nil { + return nil, err + } found, err := os.FindProcess(int(in.Pid)) if err != nil { diff --git a/grpc/server/start_scheduler.go b/grpc/server/start_scheduler.go index 307b085..5b28992 100644 --- a/grpc/server/start_scheduler.go +++ b/grpc/server/start_scheduler.go @@ -5,11 +5,9 @@ import ( "sync" "time" - "github.com/aptible/supercronic/cronexpr" pb "github.com/dunstorm/pm2-go/proto" "github.com/dunstorm/pm2-go/shared" "github.com/dunstorm/pm2-go/utils" - "google.golang.org/protobuf/types/known/timestamppb" ) func updateProcessMap(handler *Handler, processId int32, p *os.Process) { @@ -33,7 +31,7 @@ func restartProcess(handler *Handler, p *pb.Process) { p.AutoRestart = false p.SetToStop(true) p.SetStatus("stopped") - p.Pid = 0 + p.ResetPid() updateProcessMap(handler, p.Id, nil) handler.logger.Error().Msgf("Error while restarting process %s: %s", p.Name, err) @@ -66,6 +64,7 @@ func startScheduler(handler *Handler) { p.UpdateUptime() p.ResetPid() p.UpdateStatus("stopped") + p.ResetCPUMemory() updateProcessMap(handler, p.Id, nil) if p.AutoRestart && !p.GetToStop() { @@ -77,13 +76,7 @@ func startScheduler(handler *Handler) { } else if p.NextStartAt != nil && p.NextStartAt.AsTime().Before(time.Now()) { handler.logger.Debug().Msgf("Process %s is scheduled to start at %s", p.Name, p.NextStartAt.AsTime()) restartProcess(handler, p) - - if p.CronRestart != "" { - nextTime := cronexpr.MustParse(p.CronRestart).Next(time.Now()) - p.NextStartAt = timestamppb.New(nextTime) - } else { - p.NextStartAt = nil - } + p.UpdateNextStartAt() } wg.Done() } diff --git a/grpc/server/stop_process.go b/grpc/server/stop_process.go index 38c0ac9..cf24b98 100644 --- a/grpc/server/stop_process.go +++ b/grpc/server/stop_process.go @@ -16,7 +16,7 @@ func (api *Handler) StopProcess(ctx context.Context, in *pb.StopProcessRequest) found := api.processes[in.Id] process.SetStatus("stopped") - process.Pid = 0 + process.ResetCPUMemory() process.StopNext = true if found == nil { @@ -39,12 +39,15 @@ func (api *Handler) StopProcess(ctx context.Context, in *pb.StopProcessRequest) Success: false, }, nil } + process.ResetPid() return &pb.StopProcessResponse{ Success: true, }, nil } + process.ResetPid() + // for child process found.Kill() updateProcessMap(api, in.Id, nil) diff --git a/proto/process_extended.go b/proto/process_extended.go index 2ad3f9c..588e8a8 100644 --- a/proto/process_extended.go +++ b/proto/process_extended.go @@ -7,6 +7,8 @@ import ( "strings" "time" + "github.com/aptible/supercronic/cronexpr" + status "google.golang.org/grpc/status" durationpb "google.golang.org/protobuf/types/known/durationpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" ) @@ -29,6 +31,7 @@ func (p *Process) GetToStop() bool { func (p *Process) ResetPid() { p.Pid = 0 + p.ProcStatus.ParentPid = 0 } func (p *Process) UpdateUptime() { @@ -75,3 +78,15 @@ func (p *Process) UpdateCPUMemory() { memory = memory / 1024 p.ProcStatus.Memory = fmt.Sprintf("%.1fMB", memory) } + +func (p *Process) UpdateNextStartAt() error { + if p.CronRestart != "" { + expr, err := cronexpr.Parse(p.CronRestart) + if err != nil { + p.CronRestart = "" + return status.Errorf(400, "invalid cron expression: %v", err) + } + p.NextStartAt = timestamppb.New(expr.Next(time.Now())) + } + return nil +}