From 4d7d7a850107ed4188d358e5a704743f6c727ef5 Mon Sep 17 00:00:00 2001 From: Seth Brasile Date: Mon, 29 Apr 2024 20:11:15 -0500 Subject: [PATCH 1/7] hold cleanup until procKilledCh signal --- runner/engine.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/runner/engine.go b/runner/engine.go index 69db92d4..26ebb24e 100644 --- a/runner/engine.go +++ b/runner/engine.go @@ -30,6 +30,7 @@ type Engine struct { buildRunStopCh chan bool binStopCh chan bool exitCh chan bool + procKilledCh chan bool mu sync.RWMutex watchers uint @@ -58,6 +59,7 @@ func NewEngineWithConfig(cfg *Config, debugMode bool) (*Engine, error) { buildRunStopCh: make(chan bool, 1), binStopCh: make(chan bool), exitCh: make(chan bool), + procKilledCh: make(chan bool), fileChecksums: &checksumMap{m: make(map[string]string)}, watchers: 0, } @@ -504,11 +506,13 @@ func (e *Engine) runBin() error { } cmdBinPath := cmdPath(e.config.rel(e.config.binPath())) if _, err = os.Stat(cmdBinPath); os.IsNotExist(err) { + e.procKilledCh <- true return } if err = os.Remove(cmdBinPath); err != nil { e.mainLog("failed to remove %s, error: %s", e.config.rel(e.config.binPath()), err) } + e.procKilledCh <- true } e.runnerLog("running...") @@ -607,7 +611,8 @@ func (e *Engine) cleanup() { } e.mainDebug("waiting for exit...") - + <-e.procKilledCh + close(e.procKilledCh) e.running = false e.mainDebug("exited") } From 0dcd9c5e9fde444392659b755b87c8566454d450 Mon Sep 17 00:00:00 2001 From: Seth Brasile Date: Mon, 29 Apr 2024 20:19:42 -0500 Subject: [PATCH 2/7] signal to procKilledChan in existing deferred func --- runner/engine.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runner/engine.go b/runner/engine.go index 26ebb24e..cfd311a6 100644 --- a/runner/engine.go +++ b/runner/engine.go @@ -492,6 +492,7 @@ func (e *Engine) runBin() error { e.mainDebug("trying to kill pid %d, cmd %+v", cmd.Process.Pid, cmd.Args) defer func() { + e.procKilledCh <- true stdout.Close() stderr.Close() }() @@ -506,13 +507,11 @@ func (e *Engine) runBin() error { } cmdBinPath := cmdPath(e.config.rel(e.config.binPath())) if _, err = os.Stat(cmdBinPath); os.IsNotExist(err) { - e.procKilledCh <- true return } if err = os.Remove(cmdBinPath); err != nil { e.mainLog("failed to remove %s, error: %s", e.config.rel(e.config.binPath()), err) } - e.procKilledCh <- true } e.runnerLog("running...") From fec348c04b755ff4571880191692081bc6b81841 Mon Sep 17 00:00:00 2001 From: Seth Brasile Date: Tue, 30 Apr 2024 01:41:31 -0500 Subject: [PATCH 3/7] without this can't exit when non zero exit code it seems like `os.Exit(state.ExitCode())` belongs here... but unclear on intent of `e.config.Build.Rerun` This at least lets you ctrl+c out of error condition instead of killing pid via external means. --- runner/engine.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runner/engine.go b/runner/engine.go index cfd311a6..0e8431b2 100644 --- a/runner/engine.go +++ b/runner/engine.go @@ -567,6 +567,8 @@ func (e *Engine) runBin() error { e.runnerLog("Process Exit with Code: %v", state.ExitCode()) } + e.procKilledCh <- true + if !e.config.Build.Rerun { return } From 7034632575ae18432960f7db12e08e2578d963cf Mon Sep 17 00:00:00 2001 From: Seth Brasile Date: Tue, 30 Apr 2024 02:07:20 -0500 Subject: [PATCH 4/7] Revert "without this can't exit when non zero exit code" This reverts commit fec348c04b755ff4571880191692081bc6b81841. --- runner/engine.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/runner/engine.go b/runner/engine.go index 0e8431b2..cfd311a6 100644 --- a/runner/engine.go +++ b/runner/engine.go @@ -567,8 +567,6 @@ func (e *Engine) runBin() error { e.runnerLog("Process Exit with Code: %v", state.ExitCode()) } - e.procKilledCh <- true - if !e.config.Build.Rerun { return } From 674a5b93459bb5e9b9214d0fd8aae716f4e94d55 Mon Sep 17 00:00:00 2001 From: xiantang Date: Sun, 23 Jun 2024 22:26:14 +0800 Subject: [PATCH 5/7] use cleanup --- go.mod | 2 +- runner/engine.go | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 6e69bdb9..d952500d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cosmtrek/air -go 1.22 +go 1.21 require ( dario.cat/mergo v1.0.0 diff --git a/runner/engine.go b/runner/engine.go index ee64738f..d373eb35 100644 --- a/runner/engine.go +++ b/runner/engine.go @@ -31,8 +31,8 @@ type Engine struct { buildRunStopCh chan bool binStopCh chan bool exitCh chan bool - procKilledCh chan bool + cleanupWg sync.WaitGroup mu sync.RWMutex watchers uint round uint64 @@ -61,7 +61,6 @@ func NewEngineWithConfig(cfg *Config, debugMode bool) (*Engine, error) { buildRunStopCh: make(chan bool, 1), binStopCh: make(chan bool), exitCh: make(chan bool), - procKilledCh: make(chan bool), fileChecksums: &checksumMap{m: make(map[string]string)}, watchers: 0, } @@ -482,6 +481,7 @@ func (e *Engine) runPostCmd() error { } func (e *Engine) runBin() error { + e.cleanupWg.Add(1) killFunc := func(cmd *exec.Cmd, stdout io.ReadCloser, stderr io.ReadCloser, killCh chan struct{}, processExit chan struct{}, wg *sync.WaitGroup) { defer wg.Done() select { @@ -499,7 +499,6 @@ func (e *Engine) runBin() error { e.mainDebug("trying to kill pid %d, cmd %+v", cmd.Process.Pid, cmd.Args) defer func() { - e.procKilledCh <- true stdout.Close() stderr.Close() }() @@ -576,6 +575,7 @@ func (e *Engine) runBin() error { default: e.runnerLog("Process Exit with Code: %v", state.ExitCode()) } + e.cleanupWg.Done() if !e.config.Build.Rerun { return @@ -625,8 +625,7 @@ func (e *Engine) cleanup() { } e.mainDebug("waiting for exit...") - <-e.procKilledCh - close(e.procKilledCh) + e.cleanupWg.Wait() e.running = false e.mainDebug("exited") } From a759095e3cdfe526018d731b1399491ecff1d787 Mon Sep 17 00:00:00 2001 From: xiantang Date: Sun, 23 Jun 2024 23:03:10 +0800 Subject: [PATCH 6/7] fix test case rerun --- runner/engine.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runner/engine.go b/runner/engine.go index d373eb35..73e39ef0 100644 --- a/runner/engine.go +++ b/runner/engine.go @@ -32,7 +32,7 @@ type Engine struct { binStopCh chan bool exitCh chan bool - cleanupWg sync.WaitGroup + procKillWg sync.WaitGroup mu sync.RWMutex watchers uint round uint64 @@ -481,7 +481,6 @@ func (e *Engine) runPostCmd() error { } func (e *Engine) runBin() error { - e.cleanupWg.Add(1) killFunc := func(cmd *exec.Cmd, stdout io.ReadCloser, stderr io.ReadCloser, killCh chan struct{}, processExit chan struct{}, wg *sync.WaitGroup) { defer wg.Done() select { @@ -540,6 +539,7 @@ func (e *Engine) runBin() error { case <-killCh: return default: + e.procKillWg.Add(1) command := strings.Join(append([]string{e.config.Build.Bin}, e.runArgs...), " ") cmd, stdout, stderr, _ := e.startCmd(command) processExit := make(chan struct{}) @@ -575,7 +575,7 @@ func (e *Engine) runBin() error { default: e.runnerLog("Process Exit with Code: %v", state.ExitCode()) } - e.cleanupWg.Done() + e.procKillWg.Done() if !e.config.Build.Rerun { return @@ -625,7 +625,7 @@ func (e *Engine) cleanup() { } e.mainDebug("waiting for exit...") - e.cleanupWg.Wait() + e.procKillWg.Wait() e.running = false e.mainDebug("exited") } From 609de5aebb5303da945406fed8129b8ee14e7941 Mon Sep 17 00:00:00 2001 From: xiantang Date: Sun, 23 Jun 2024 23:06:42 +0800 Subject: [PATCH 7/7] upgrade gomod version --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index d952500d..6e69bdb9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cosmtrek/air -go 1.21 +go 1.22 require ( dario.cat/mergo v1.0.0