agent: simplify signal handling

pull/3108/head
Frank Schroeder 8 years ago committed by Frank Schröder
parent 34fd31b7b1
commit 96d8035adc

@ -28,9 +28,6 @@ import (
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
// gracefulTimeout controls how long we wait before forcefully terminating
var gracefulTimeout = 5 * time.Second
// validDatacenter is used to validate a datacenter // validDatacenter is used to validate a datacenter
var validDatacenter = regexp.MustCompile("^[a-zA-Z0-9_-]+$") var validDatacenter = regexp.MustCompile("^[a-zA-Z0-9_-]+$")
@ -732,81 +729,72 @@ func (cmd *Command) wait(agent *Agent, cfg *Config) int {
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP) signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGPIPE) signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGPIPE)
// Wait for a signal for {
WAIT: var sig os.Signal
var sig os.Signal var reloadErrCh chan error
var reloadErrCh chan error select {
select { case s := <-signalCh:
case s := <-signalCh: sig = s
sig = s case ch := <-agent.ReloadCh():
case ch := <-agent.ReloadCh(): sig = syscall.SIGHUP
sig = syscall.SIGHUP reloadErrCh = ch
reloadErrCh = ch case <-cmd.ShutdownCh:
case <-cmd.ShutdownCh: sig = os.Interrupt
sig = os.Interrupt case err := <-agent.RetryJoinCh():
case err := <-agent.RetryJoinCh(): cmd.UI.Error(err.Error())
cmd.UI.Error(err.Error()) return 1
return 1 case <-agent.ShutdownCh():
case <-agent.ShutdownCh(): // Agent is already down!
// Agent is already shutdown! return 0
return 0 }
}
// Skip SIGPIPE signals and skip logging whenever such signal is received as well switch sig {
if sig == syscall.SIGPIPE { case syscall.SIGPIPE:
goto WAIT continue
}
cmd.UI.Output(fmt.Sprintf("Caught signal: %v", sig)) case syscall.SIGHUP:
cmd.UI.Output(fmt.Sprintf("Caught signal: %v", sig))
// Check if this is a SIGHUP conf, err := cmd.handleReload(agent, cfg)
if sig == syscall.SIGHUP { if conf != nil {
conf, err := cmd.handleReload(agent, cfg) cfg = conf
if conf != nil { }
cfg = conf if err != nil {
} cmd.UI.Error(err.Error())
if err != nil { }
cmd.UI.Error(err.Error()) // Send result back if reload was called via HTTP
} if reloadErrCh != nil {
// Send result back if reload was called via HTTP reloadErrCh <- err
if reloadErrCh != nil { }
reloadErrCh <- err
}
goto WAIT
}
// Check if we should do a graceful leave default:
graceful := false cmd.UI.Output(fmt.Sprintf("Caught signal: %v", sig))
if sig == os.Interrupt && !(*cfg.SkipLeaveOnInt) {
graceful = true
} else if sig == syscall.SIGTERM && (*cfg.LeaveOnTerm) {
graceful = true
}
// Bail fast if not doing a graceful leave graceful := (sig == os.Interrupt && !(*cfg.SkipLeaveOnInt)) || (sig == syscall.SIGTERM && (*cfg.LeaveOnTerm))
if !graceful { if !graceful {
return 1 return 1
} }
// Attempt a graceful leave cmd.UI.Output("Gracefully shutting down agent...")
gracefulCh := make(chan struct{}) gracefulCh := make(chan struct{})
cmd.UI.Output("Gracefully shutting down agent...") go func() {
go func() { if err := agent.Leave(); err != nil {
if err := agent.Leave(); err != nil { cmd.UI.Error(fmt.Sprintf("Error: %s", err))
cmd.UI.Error(fmt.Sprintf("Error: %s", err)) return
return }
close(gracefulCh)
}()
gracefulTimeout := 5 * time.Second
select {
case <-signalCh:
return 1
case <-time.After(gracefulTimeout):
return 1
case <-gracefulCh:
return 0
}
} }
close(gracefulCh)
}()
// Wait for leave or another signal
select {
case <-signalCh:
return 1
case <-time.After(gracefulTimeout):
return 1
case <-gracefulCh:
return 0
} }
} }

Loading…
Cancel
Save