From de95ec6606b40d16646e0587648e35deee37431e Mon Sep 17 00:00:00 2001 From: nxtcoder17 Date: Mon, 23 Sep 2024 18:34:45 +0530 Subject: [PATCH] feat: improves executor and signal handling --- main.go | 2 +- pkg/executor/exec.go | 33 +++++++++++++++++++++++---------- pkg/watcher/watcher.go | 2 +- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/main.go b/main.go index c491fe0..65c14c1 100644 --- a/main.go +++ b/main.go @@ -113,7 +113,7 @@ func main() { execArgs = cctx.Args().Tail() } - ex := executor.NewExecutor(ctx, executor.ExecutorArgs{ + ex := executor.NewExecutor(executor.ExecutorArgs{ Logger: logger, Command: func(context.Context) *exec.Cmd { cmd := exec.Command(execCmd, execArgs...) diff --git a/pkg/executor/exec.go b/pkg/executor/exec.go index 6ffae6b..95eac52 100644 --- a/pkg/executor/exec.go +++ b/pkg/executor/exec.go @@ -12,9 +12,9 @@ import ( ) type Executor struct { - ctx context.Context - done chan os.Signal - logger *slog.Logger + done chan os.Signal + logger *slog.Logger + isRunning bool newCmd func(context.Context) *exec.Cmd mu sync.Mutex @@ -25,7 +25,7 @@ type ExecutorArgs struct { Command func(context.Context) *exec.Cmd } -func NewExecutor(ctx context.Context, args ExecutorArgs) *Executor { +func NewExecutor(args ExecutorArgs) *Executor { done := make(chan os.Signal, 1) signal.Notify(done, syscall.SIGTERM) @@ -36,19 +36,24 @@ func NewExecutor(ctx context.Context, args ExecutorArgs) *Executor { return &Executor{ done: done, logger: args.Logger, - ctx: ctx, newCmd: args.Command, mu: sync.Mutex{}, } } func (ex *Executor) Exec() error { + ex.logger.Debug("[exec:pre] starting process") ex.mu.Lock() - defer ex.mu.Unlock() + ex.isRunning = true + + defer func() { + ex.isRunning = false + ex.mu.Unlock() + }() ex.logger.Debug("[exec] starting process") - ctx, cf := context.WithCancel(ex.ctx) + ctx, cf := context.WithCancel(context.TODO()) defer cf() cmd := ex.newCmd(ctx) @@ -65,9 +70,15 @@ func (ex *Executor) Exec() error { case <-ex.done: ex.logger.Debug("executor terminated", "pid", cmd.Process.Pid) } + for len(ex.done) > 0 { + <-ex.done + } + ex.logger.Debug("[exec] killing process", "pid", cmd.Process.Pid) if err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL); err != nil { - ex.logger.Error("failed to kill process", "pid", cmd.Process.Pid, "err", err) + if err.Error() != "no such process" { + ex.logger.Error("failed to kill process", "pid", cmd.Process.Pid, "err", err) + } } }() @@ -75,12 +86,14 @@ func (ex *Executor) Exec() error { if strings.HasPrefix(err.Error(), "signal:") { ex.logger.Debug("wait terminated, received", "signal", err.Error()) } - return err + ex.logger.Debug("while waiting, got", "err", err) } return nil } func (ex *Executor) Kill() { - ex.done <- os.Signal(syscall.SIGTERM) + if ex.isRunning { + ex.done <- os.Signal(syscall.SIGTERM) + } } diff --git a/pkg/watcher/watcher.go b/pkg/watcher/watcher.go index cae3022..0fc537e 100644 --- a/pkg/watcher/watcher.go +++ b/pkg/watcher/watcher.go @@ -92,7 +92,7 @@ func (f *fsnWatcher) WatchEvents(watcherFunc func(event Event, fp string) error) eInfo.Counter += 1 f.eventMap[event.Name] = eInfo - if time.Since(eInfo.Time) < 1*time.Second { + if time.Since(eInfo.Time) < 100*time.Millisecond { f.Logger.Debug("too many events under 1s, ignoring...", "counter", eInfo.Counter) continue }