From 45c66208a1965ad02c4e73b1309fe75358172a56 Mon Sep 17 00:00:00 2001 From: Simon Let Date: Sat, 11 Dec 2021 22:51:43 +0100 Subject: [PATCH] Ignore SIGINT and SIGQUIT, timeouts for requests --- Makefile | 2 +- cmd/daemon/kill.go | 28 ++++++++++++++++ cmd/daemon/main.go | 55 +------------------------------ cmd/daemon/status.go | 39 ++++++++++++++++++++++ pkg/httpclient/httpclient.go | 12 +++++++ pkg/signalhandler/signalhander.go | 18 +++++++--- scripts/util.sh | 3 ++ 7 files changed, 97 insertions(+), 60 deletions(-) create mode 100644 cmd/daemon/kill.go create mode 100644 cmd/daemon/status.go create mode 100644 pkg/httpclient/httpclient.go diff --git a/Makefile b/Makefile index 3dcf6fa..02bb7e0 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ install: build test: go test -v ./... go vet ./... - scripts/test.sh --all + scripts/test.sh rebuild: make clean diff --git a/cmd/daemon/kill.go b/cmd/daemon/kill.go new file mode 100644 index 0000000..7c403a9 --- /dev/null +++ b/cmd/daemon/kill.go @@ -0,0 +1,28 @@ +package main + +import ( + "io/ioutil" + "log" + "os/exec" + "strconv" + "strings" +) + +func killDaemon(pidfile string) error { + dat, err := ioutil.ReadFile(pidfile) + if err != nil { + log.Println("Reading pid file failed", err) + } + log.Print(string(dat)) + pid, err := strconv.Atoi(strings.TrimSuffix(string(dat), "\n")) + if err != nil { + log.Fatal("Pidfile contents are malformed", err) + } + cmd := exec.Command("kill", "-s", "sigint", strconv.Itoa(pid)) + err = cmd.Run() + if err != nil { + log.Printf("Command finished with error: %v", err) + return err + } + return nil +} diff --git a/cmd/daemon/main.go b/cmd/daemon/main.go index 9b59d04..2fefcbf 100644 --- a/cmd/daemon/main.go +++ b/cmd/daemon/main.go @@ -1,22 +1,17 @@ package main import ( - //"flag" - "encoding/json" + "io/ioutil" "log" - "net/http" "os" - "os/exec" "os/user" "path/filepath" "strconv" - "strings" "github.com/BurntSushi/toml" "github.com/curusarn/resh/pkg/cfg" - "github.com/curusarn/resh/pkg/msg" ) // version from git set during build @@ -89,51 +84,3 @@ func main() { } log.Println("main: Shutdown - bye") } - -func statusHandler(w http.ResponseWriter, r *http.Request) { - log.Println("/status START") - resp := msg.StatusResponse{ - Status: true, - Version: version, - Commit: commit, - } - jsn, err := json.Marshal(&resp) - if err != nil { - log.Println("Encoding error:", err) - log.Println("Response:", resp) - return - } - w.Write(jsn) - log.Println("/status END") -} - -func killDaemon(pidfile string) error { - dat, err := ioutil.ReadFile(pidfile) - if err != nil { - log.Println("Reading pid file failed", err) - } - log.Print(string(dat)) - pid, err := strconv.Atoi(strings.TrimSuffix(string(dat), "\n")) - if err != nil { - log.Fatal("Pidfile contents are malformed", err) - } - cmd := exec.Command("kill", "-s", "sigint", strconv.Itoa(pid)) - err = cmd.Run() - if err != nil { - log.Printf("Command finished with error: %v", err) - return err - } - return nil -} - -func isDaemonRunning(port int) (bool, error) { - url := "http://localhost:" + strconv.Itoa(port) + "/status" - resp, err := http.Get(url) - if err != nil { - log.Println("Error while checking daemon status - "+ - "it's probably not running!", err) - return false, err - } - defer resp.Body.Close() - return true, nil -} diff --git a/cmd/daemon/status.go b/cmd/daemon/status.go new file mode 100644 index 0000000..f824549 --- /dev/null +++ b/cmd/daemon/status.go @@ -0,0 +1,39 @@ +package main + +import ( + "encoding/json" + "log" + "net/http" + "strconv" + + "github.com/curusarn/resh/pkg/msg" +) + +func statusHandler(w http.ResponseWriter, r *http.Request) { + log.Println("/status START") + resp := msg.StatusResponse{ + Status: true, + Version: version, + Commit: commit, + } + jsn, err := json.Marshal(&resp) + if err != nil { + log.Println("Encoding error:", err) + log.Println("Response:", resp) + return + } + w.Write(jsn) + log.Println("/status END") +} + +func isDaemonRunning(port int) (bool, error) { + url := "http://localhost:" + strconv.Itoa(port) + "/status" + resp, err := http.Get(url) + if err != nil { + log.Println("Error while checking daemon status - "+ + "it's probably not running!", err) + return false, err + } + defer resp.Body.Close() + return true, nil +} diff --git a/pkg/httpclient/httpclient.go b/pkg/httpclient/httpclient.go new file mode 100644 index 0000000..c2d1702 --- /dev/null +++ b/pkg/httpclient/httpclient.go @@ -0,0 +1,12 @@ +package httpclient + +import ( + "net/http" + "time" +) + +func New() *http.Client { + return &http.Client{ + Timeout: 100 * time.Millisecond, + } +} diff --git a/pkg/signalhandler/signalhander.go b/pkg/signalhandler/signalhander.go index c3c201b..22e0c6a 100644 --- a/pkg/signalhandler/signalhander.go +++ b/pkg/signalhandler/signalhander.go @@ -25,7 +25,7 @@ func sendSignals(sig os.Signal, subscribers []chan os.Signal, done chan string) case _ = <-done: chanCount-- if chanCount == 0 { - log.Println("signalhandler: All boxes shut down successfully") + log.Println("signalhandler: All components shut down successfully") return } default: @@ -42,12 +42,20 @@ func sendSignals(sig os.Signal, subscribers []chan os.Signal, done chan string) func Run(subscribers []chan os.Signal, done chan string, server *http.Server) { signals := make(chan os.Signal, 1) - signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) + signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGQUIT) - sig := <-signals - log.Println("signalhandler: Got signal " + sig.String()) + var sig os.Signal + for { + sig := <-signals + log.Println("signalhandler: Got signal " + sig.String()) + if sig == syscall.SIGTERM { + // Shutdown daemon on SIGTERM + break + } + log.Printf("signalhandler: Ignoring signal %s. Send SIGTERM to trigger shutdown.\n", sig.String()) + } - log.Println("signalhandler: Sending signals to Subscribers") + log.Println("signalhandler: Sending shutdown signals to components") sendSignals(sig, subscribers, done) log.Println("signalhandler: Shutting down the server") diff --git a/scripts/util.sh b/scripts/util.sh index 12b3f64..4bb298e 100644 --- a/scripts/util.sh +++ b/scripts/util.sh @@ -53,6 +53,9 @@ __resh_run_daemon() { # hotfix gnohup resh-daemon >| ~/.resh/daemon_last_run_out.txt 2>&1 & disown else + # TODO: switch to nohup for consistency once you confirm that daemon is + # not getting killed anymore on macOS + # nohup resh-daemon >| ~/.resh/daemon_last_run_out.txt 2>&1 & disown setsid resh-daemon >| ~/.resh/daemon_last_run_out.txt 2>&1 & disown fi }