From 27b6ac0a58f6d426cc65e9d109ac845684f540d7 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Wed, 3 Apr 2019 11:07:11 -0700 Subject: [PATCH] Add INT and TERM signal handler. --- ca/signal.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/ca/signal.go b/ca/signal.go index 1b74ac4a..0d950435 100644 --- a/ca/signal.go +++ b/ca/signal.go @@ -7,6 +7,12 @@ import ( "syscall" ) +// Stopper is the interface that external commands can implement to stop the +// server. +type Stopper interface { + Stop() error +} + // StopReloader is the interface that external commands can implement to stop // the server and reload the configuration while running. type StopReloader interface { @@ -14,6 +20,32 @@ type StopReloader interface { Reload() error } +// StopHandler watches SIGINT, SIGTERM on a list of servers implementing the +// Stopper interface, and when one of those signals is caught we'll run Stop +// (SIGINT, SIGTERM) on all servers. +func StopHandler(servers ...Stopper) { + signals := make(chan os.Signal, 1) + signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) + defer signal.Stop(signals) + + for { + select { + case sig := <-signals: + switch sig { + case syscall.SIGINT, syscall.SIGTERM: + log.Println("shutting down ...") + for _, server := range servers { + err := server.Stop() + if err != nil { + log.Printf("error stopping server: %s", err.Error()) + } + } + return + } + } + } +} + // StopReloaderHandler watches SIGINT, SIGTERM and SIGHUP on a list of servers // implementing the StopReloader interface, and when one of those signals is // caught we'll run Stop (SIGINT, SIGTERM) or Reload (SIGHUP) on all servers.