Gracefully handle SIGINT

This commit is contained in:
simon 2019-07-17 21:49:51 -04:00
parent dc954bc85b
commit 1362aae61a
3 changed files with 35 additions and 10 deletions

View File

@ -6,6 +6,8 @@ import (
"os"
"os/exec"
"path/filepath"
"sync"
"syscall"
"time"
)
@ -16,6 +18,7 @@ type Beemer struct {
beemChan chan string
watcher *fsnotify.Watcher
inactiveDelay time.Duration
globalWg *sync.WaitGroup
}
type File struct {
@ -132,12 +135,11 @@ func (b Beemer) handleWatcherEvents() {
}
func (b Beemer) work() {
for {
select {
case name := <-b.beemChan:
b.beemFile(name)
}
b.globalWg.Add(1)
for name := range b.beemChan {
b.beemFile(name)
}
b.globalWg.Done()
}
func (b Beemer) handleFileInactive(t *time.Timer, name string) {
@ -159,6 +161,12 @@ func (b Beemer) beemFile(filename string) {
name, args := b.beemCommand(newName, filepath.Dir(filename))
cmd := exec.Command(name, args...)
// Don't send SIGINT to child processes
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
out, err := cmd.CombinedOutput()
if err != nil {
logrus.WithField("name", filename).WithError(err).Error(string(out))

16
cli.go
View File

@ -6,10 +6,14 @@ import (
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
func globalInit() {
//TODO cmdline flag
logrus.SetLevel(logrus.TraceLevel)
}
@ -66,14 +70,13 @@ func main() {
beemChan: make(chan string, transfers),
beemCommand: parseCommand(cmdString),
inactiveDelay: inactiveDelay,
globalWg: &sync.WaitGroup{},
}
beemer.initTempDir()
beemer.watcher, _ = fsnotify.NewWatcher()
defer beemer.dispose()
go beemer.handleWatcherEvents()
beemer.initWatchDir(watchDir)
@ -82,10 +85,13 @@ func main() {
go beemer.work()
}
//TODO gracefully handle SIGINT
done := make(chan bool)
<-done
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT)
defer beemer.dispose()
<-sigChan
logrus.Info("Received SIGINT")
return nil
}

11
util.go
View File

@ -108,8 +108,19 @@ func isDir(name string) bool {
func (b Beemer) dispose() {
b.watcher.Close()
close(b.beemChan)
logrus.WithField("chanLen", len(b.beemChan)).Info("Waiting for beem queue to drain...")
<-b.beemChan
logrus.Info("Waiting for current commands to finish...")
b.globalWg.Wait()
logrus.Info("Cleaning up temp dir...")
err := os.RemoveAll(b.tempDir)
if err != nil {
logrus.Fatal(err)
}
logrus.Info("Goodbye.")
}