From dbc4b683018c65d622c712c76eb217e11f9494a0 Mon Sep 17 00:00:00 2001 From: Alvaro Saurin Date: Mon, 27 Apr 2015 13:27:53 +0200 Subject: [PATCH 1/3] Use a general signals handler --- common/signals.go | 38 ++++++++++++++++++++++++++++++++++++++ weavedns/main.go | 28 +++------------------------- 2 files changed, 41 insertions(+), 25 deletions(-) create mode 100644 common/signals.go diff --git a/common/signals.go b/common/signals.go new file mode 100644 index 00000000..067bf340 --- /dev/null +++ b/common/signals.go @@ -0,0 +1,38 @@ +package common + +import ( + "os" + "os/signal" + "runtime" + "syscall" +) + +// A subsystem/server/... that can be stopped or queried about the status with a signal +type SignalsReceiver interface { + Status() string + Stop() error +} + +func SignalHandlerLoop(ss ...SignalsReceiver) { + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGUSR1) + buf := make([]byte, 1<<20) + for { + sig := <-sigs + switch sig { + case syscall.SIGINT: + Info.Printf("=== received SIGINT ===\n*** exiting\n") + for _, subsystem := range ss { + subsystem.Stop() + } + os.Exit(0) + case syscall.SIGQUIT: + stacklen := runtime.Stack(buf, true) + Info.Printf("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end\n", buf[:stacklen]) + case syscall.SIGUSR1: + for _, subsystem := range ss { + Info.Printf("=== received SIGUSR1 ===\n*** status...\n%s\n*** end\n", subsystem.Status()) + } + } + } +} diff --git a/weavedns/main.go b/weavedns/main.go index ae1e06e8..6a888896 100644 --- a/weavedns/main.go +++ b/weavedns/main.go @@ -9,9 +9,6 @@ import ( weavenet "github.com/weaveworks/weave/net" "net" "os" - "os/signal" - "runtime" - "syscall" ) var version = "(unreleased version)" @@ -90,30 +87,11 @@ func main() { } Info.Println("Upstream", srv.Upstream) - Debug.Printf("Starting the signals handler") - go handleSignals(srv) - + go SignalHandlerLoop(srv) go weavedns.ListenHTTP(version, srv, domain, zone, httpPort) + err = srv.Start() if err != nil { - Error.Fatal("Failed to start the WeaveDNS server", err) - } -} - -func handleSignals(s *weavedns.DNSServer) { - sigs := make(chan os.Signal, 1) - signal.Notify(sigs, syscall.SIGINT, syscall.SIGQUIT) - buf := make([]byte, 1<<20) - for { - sig := <-sigs - switch sig { - case syscall.SIGINT: - Info.Printf("=== received SIGINT ===\n*** exiting\n") - s.Stop() - os.Exit(0) - case syscall.SIGQUIT: - stacklen := runtime.Stack(buf, true) - Info.Printf("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end\n", buf[:stacklen]) - } + Error.Fatal("[main] Failed to start the WeaveDNS server: ", err) } } From f723d5afd8f2dc055e2b657bdc51114876f166c3 Mon Sep 17 00:00:00 2001 From: Alvaro Saurin Date: Wed, 6 May 2015 12:01:36 +0200 Subject: [PATCH 2/3] Move the router to the new signals handler --- router/router.go | 5 +++++ weaver/main.go | 22 +++------------------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/router/router.go b/router/router.go index 63f0641f..f6118761 100644 --- a/router/router.go +++ b/router/router.go @@ -94,6 +94,11 @@ func (router *Router) Start() { } } +func (router *Router) Stop() error { + // TODO: perform greceful shutdown... + return nil +} + func (router *Router) UsingPassword() bool { return router.Password != nil } diff --git a/weaver/main.go b/weaver/main.go index 614d1db7..12335c57 100644 --- a/weaver/main.go +++ b/weaver/main.go @@ -7,16 +7,15 @@ import ( "fmt" "github.com/davecheney/profile" "github.com/gorilla/mux" + . "github.com/weaveworks/weave/common" weavenet "github.com/weaveworks/weave/net" weave "github.com/weaveworks/weave/router" "log" "net" "net/http" "os" - "os/signal" "runtime" "strings" - "syscall" ) var version = "(unreleased version)" @@ -126,7 +125,8 @@ func main() { if httpAddr != "" { go handleHTTP(router, httpAddr) } - handleSignals(router) + + SignalHandlerLoop(router) } func options() map[string]string { @@ -209,19 +209,3 @@ func handleHTTP(router *weave.Router, httpAddr string) { log.Fatal("Unable to create http server", err) } } - -func handleSignals(router *weave.Router) { - sigs := make(chan os.Signal, 1) - signal.Notify(sigs, syscall.SIGQUIT, syscall.SIGUSR1) - buf := make([]byte, 1<<20) - for { - sig := <-sigs - switch sig { - case syscall.SIGQUIT: - stacklen := runtime.Stack(buf, true) - log.Printf("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end\n", buf[:stacklen]) - case syscall.SIGUSR1: - log.Printf("=== received SIGUSR1 ===\n*** status...\n%s\n*** end\n", router.Status()) - } - } -} From 14b99fac2a02b81fbe7b9ddc9fb708cba054bf35 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Wed, 6 May 2015 19:39:44 +0100 Subject: [PATCH 3/3] minor refactors --- common/signals.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/common/signals.go b/common/signals.go index 067bf340..fdc49119 100644 --- a/common/signals.go +++ b/common/signals.go @@ -8,18 +8,17 @@ import ( ) // A subsystem/server/... that can be stopped or queried about the status with a signal -type SignalsReceiver interface { - Status() string +type SignalReceiver interface { Stop() error + Status() string } -func SignalHandlerLoop(ss ...SignalsReceiver) { +func SignalHandlerLoop(ss ...SignalReceiver) { sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGUSR1) buf := make([]byte, 1<<20) for { - sig := <-sigs - switch sig { + switch <-sigs { case syscall.SIGINT: Info.Printf("=== received SIGINT ===\n*** exiting\n") for _, subsystem := range ss {