Skip to content

Commit

Permalink
ensure multiple processes stop to avoid address already in use errors (
Browse files Browse the repository at this point in the history
…#254)

* ensure multiple processes stop to avoid  address already in use errors

* add code cov
  • Loading branch information
nwadams authored Feb 22, 2022
1 parent 06f09d9 commit 673a832
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
38 changes: 20 additions & 18 deletions runner/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ type Engine struct {
buildRunCh chan bool
buildRunStopCh chan bool
canExit chan bool
binStopCh chan bool
binStopChMap map[int]chan bool
exitCh chan bool

mu sync.RWMutex
binRunning bool
watchers uint
fileChecksums *checksumMap

Expand Down Expand Up @@ -58,9 +57,8 @@ func NewEngine(cfgPath string, debugMode bool) (*Engine, error) {
buildRunCh: make(chan bool, 1),
buildRunStopCh: make(chan bool, 1),
canExit: make(chan bool, 1),
binStopCh: make(chan bool),
binStopChMap: make(map[int]chan bool),
exitCh: make(chan bool),
binRunning: false,
watchers: 0,
}

Expand Down Expand Up @@ -342,9 +340,10 @@ func (e *Engine) start() {

// if current app is running, stop it
e.withLock(func() {
if e.binRunning {
e.binStopCh <- true
for _, v := range e.binStopChMap {
v <- true
}
e.binStopChMap = make(map[int]chan bool)
})
go e.buildRun()
}
Expand Down Expand Up @@ -424,20 +423,16 @@ func (e *Engine) runBin() error {
if err != nil {
return err
}
e.withLock(func() {
e.binRunning = true
})
e.mainDebug("running process pid %v", cmd.Process.Pid)

go func(cmd *exec.Cmd, stdin io.WriteCloser, stdout io.ReadCloser, stderr io.ReadCloser) {
killFunc := func(cmd *exec.Cmd, stdin io.WriteCloser, stdout io.ReadCloser, stderr io.ReadCloser, binStopChan chan bool) {
defer func() {
select {
case <-e.exitCh:
close(e.canExit)
default:
}
}()
<-e.binStopCh
<-binStopChan
e.mainDebug("trying to kill pid %d, cmd %+v", cmd.Process.Pid, cmd.Args)
defer func() {
stdout.Close()
Expand All @@ -453,17 +448,23 @@ func (e *Engine) runBin() error {
} else {
e.mainDebug("cmd killed, pid: %d", pid)
}
e.withLock(func() {
e.binRunning = false
})
cmdBinPath := cmdPath(e.config.rel(e.config.binPath()))
if _, err = os.Stat(cmdBinPath); os.IsNotExist(err) {
return
}
if err = os.Remove(cmdBinPath); err != nil {
e.mainLog("failed to remove %s, error: %s", e.config.rel(e.config.binPath()), err)
}
}(cmd, stdin, stdout, stderr)
}
e.withLock(func() {
for _, v := range e.binStopChMap {
v <- true
}
e.binStopChMap = make(map[int]chan bool)
e.binStopChMap[cmd.Process.Pid] = make(chan bool)
go killFunc(cmd, stdin, stdout, stderr, e.binStopChMap[cmd.Process.Pid])
})
e.mainDebug("running process pid %v", cmd.Process.Pid)
return nil
}

Expand All @@ -472,9 +473,10 @@ func (e *Engine) cleanup() {
defer e.mainLog("see you again~")

e.withLock(func() {
if e.binRunning {
e.binStopCh <- true
for _, v := range e.binStopChMap {
v <- true
}
e.binStopChMap = make(map[int]chan bool)
})
e.mainDebug("wating for close watchers..")

Expand Down
21 changes: 21 additions & 0 deletions runner/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,24 @@ func TestRegexes(t *testing.T) {
t.Errorf("expected '%t' but got '%t'", false, result)
}
}

func TestRunBin(t *testing.T) {
engine, err := NewEngine("", true)
if err != nil {
t.Fatalf("Should not be fail: %s.", err)
}

err = engine.runBin()
if err != nil {
t.Fatalf("Should not be fail: %s.", err)
}
}

func TestBuildRun(t *testing.T) {
engine, err := NewEngine("", true)
if err != nil {
t.Fatalf("Should not be fail: %s.", err)
}

engine.buildRun()
}

0 comments on commit 673a832

Please sign in to comment.