From 654eb6fd993977b87d6a3cbd7b0a7f18d5e73288 Mon Sep 17 00:00:00 2001 From: "H.Muraoka" Date: Fri, 17 Jan 2020 08:01:27 +0000 Subject: [PATCH 1/7] Add CANCELLATION_DELAY_SECONDS to README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 183c2a5..37fcf8e 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,11 @@ Commands using this framework implement these external specifications: This is used internally for graceful restart. +* `CANCELLATION_DELAY_SECONDS` + + After `SIGINT` or `SIGTERM` received, the signal handler waits for the seconds before cancelling the context. + The default value is 5 sec. + Usage ----- From f4d0d3d98aa791f8cc5d370fda23e0ac5f8f4fa5 Mon Sep 17 00:00:00 2001 From: "H.Muraoka" Date: Fri, 17 Jan 2020 08:38:35 +0000 Subject: [PATCH 2/7] Add context cancellation delay seconds --- go.mod | 2 ++ signal.go | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/go.mod b/go.mod index a073298..abaa076 100644 --- a/go.mod +++ b/go.mod @@ -8,3 +8,5 @@ require ( github.com/spf13/viper v1.3.2 golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72 ) + +go 1.13 diff --git a/signal.go b/signal.go index b4d329a..ed09a77 100644 --- a/signal.go +++ b/signal.go @@ -4,12 +4,18 @@ import ( "errors" "os" "os/signal" + "strconv" + "time" "github.com/cybozu-go/log" ) var ( errSignaled = errors.New("signaled") + + cancellationDelaySecondsEnv = "CANCELLATION_DELAY_SECONDS" + + defaultCancellationDelaySeconds = 5 ) // IsSignaled returns true if err returned by Wait indicates that @@ -28,6 +34,23 @@ func handleSignal(env *Environment) { log.Warn("well: got signal", map[string]interface{}{ "signal": s.String(), }) + delayStr := os.Getenv(cancellationDelaySecondsEnv) + delay, err := strconv.Atoi(delayStr) + if err != nil { + log.Warn("well: set default cancellation delay seconds", map[string]interface{}{ + "env": delayStr, + "delay": defaultCancellationDelaySeconds, + }) + delay = defaultCancellationDelaySeconds + } + if delay < 0 { + log.Warn("well: round up negative cancellation delay seconds to 0s", map[string]interface{}{ + "env": delayStr, + "delay": 0, + }) + delay = 0 + } + time.Sleep(time.Duration(delay) * time.Second) env.Cancel(errSignaled) }() } From 0d099ae119b95946e49ae243c6eb02765b2f8311 Mon Sep 17 00:00:00 2001 From: "H.Muraoka" Date: Fri, 17 Jan 2020 08:45:07 +0000 Subject: [PATCH 3/7] Fix test to wait for 6 seconds --- test/restart/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/restart/main.go b/test/restart/main.go index c39b7c0..4470b3f 100644 --- a/test/restart/main.go +++ b/test/restart/main.go @@ -144,7 +144,7 @@ func ping(network, addr string) error { "data": string(data), }) - if time.Since(st) > time.Second { + if time.Since(st) > 6*time.Second { return errors.New("too long") } return nil From 00e959dc2b270eef09547505664a24dec0769117 Mon Sep 17 00:00:00 2001 From: "H.Muraoka" Date: Fri, 17 Jan 2020 08:58:06 +0000 Subject: [PATCH 4/7] Reflect comment --- signal.go | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/signal.go b/signal.go index ed09a77..52c406f 100644 --- a/signal.go +++ b/signal.go @@ -34,23 +34,34 @@ func handleSignal(env *Environment) { log.Warn("well: got signal", map[string]interface{}{ "signal": s.String(), }) - delayStr := os.Getenv(cancellationDelaySecondsEnv) - delay, err := strconv.Atoi(delayStr) - if err != nil { - log.Warn("well: set default cancellation delay seconds", map[string]interface{}{ - "env": delayStr, - "delay": defaultCancellationDelaySeconds, - }) - delay = defaultCancellationDelaySeconds - } - if delay < 0 { - log.Warn("well: round up negative cancellation delay seconds to 0s", map[string]interface{}{ - "env": delayStr, - "delay": 0, - }) - delay = 0 - } + delay := getDelaySecondsFromEnv() time.Sleep(time.Duration(delay) * time.Second) env.Cancel(errSignaled) }() } + +func getDelaySecondsFromEnv() int { + delayStr := os.Getenv(cancellationDelaySecondsEnv) + if len(delayStr) <= 0 { + return defaultCancellationDelaySeconds + } + + delay, err := strconv.Atoi(delayStr) + if err != nil { + log.Warn("well: set default cancellation delay seconds", map[string]interface{}{ + "env": delayStr, + "delay": defaultCancellationDelaySeconds, + log.FnError: err, + }) + return defaultCancellationDelaySeconds + } + if delay < 0 { + log.Warn("well: round up negative cancellation delay seconds to 0s", map[string]interface{}{ + "env": delayStr, + "delay": 0, + log.FnError: err, + }) + return 0 + } + return delay +} From 300068ebf2e4c3bc98a4dc76bc2a8110587d0b1e Mon Sep 17 00:00:00 2001 From: "H.Muraoka" Date: Fri, 17 Jan 2020 09:13:08 +0000 Subject: [PATCH 5/7] Fix test to run with delay=0 --- .circleci/config.yml | 2 +- test/restart/main.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4f30609..2d42cb7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ jobs: - run: go vet . - run: | go build ./test/restart - ./restart + CANCELLATION_DELAY_SECONDS=0 ./restart - run: | cd ./test/spf13 cp main.go_ main.go diff --git a/test/restart/main.go b/test/restart/main.go index 4470b3f..2c69481 100644 --- a/test/restart/main.go +++ b/test/restart/main.go @@ -136,7 +136,7 @@ func ping(network, addr string) error { } if string(data) != "hello 1" { log.Error("wrong response", map[string]interface{}{ - "data": data, + "data": string(data), }) return errors.New("invalid response") } @@ -144,7 +144,7 @@ func ping(network, addr string) error { "data": string(data), }) - if time.Since(st) > 6*time.Second { + if time.Since(st) > time.Second { return errors.New("too long") } return nil From 8c89aa0719ab457558379423dd5ebc45d393f228 Mon Sep 17 00:00:00 2001 From: Hiroshi Muraoka Date: Mon, 20 Jan 2020 04:45:31 +0000 Subject: [PATCH 6/7] Reflect comments --- signal.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/signal.go b/signal.go index 52c406f..c405372 100644 --- a/signal.go +++ b/signal.go @@ -42,7 +42,7 @@ func handleSignal(env *Environment) { func getDelaySecondsFromEnv() int { delayStr := os.Getenv(cancellationDelaySecondsEnv) - if len(delayStr) <= 0 { + if len(delayStr) == 0 { return defaultCancellationDelaySeconds } @@ -57,9 +57,8 @@ func getDelaySecondsFromEnv() int { } if delay < 0 { log.Warn("well: round up negative cancellation delay seconds to 0s", map[string]interface{}{ - "env": delayStr, - "delay": 0, - log.FnError: err, + "env": delayStr, + "delay": 0, }) return 0 } From a36433915343623160c45f2d7b47ea60da06faf8 Mon Sep 17 00:00:00 2001 From: Hiroshi Muraoka Date: Mon, 20 Jan 2020 04:48:12 +0000 Subject: [PATCH 7/7] Inherit environment variables to child --- graceful_unix.go | 3 ++- signal.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/graceful_unix.go b/graceful_unix.go index ccdb019..d1ddbab 100644 --- a/graceful_unix.go +++ b/graceful_unix.go @@ -198,7 +198,8 @@ RESTART: func (g *Graceful) makeChild(files []*os.File) *exec.Cmd { child := exec.Command(os.Args[0], os.Args[1:]...) - child.Env = []string{listenEnv + "=" + strconv.Itoa(len(files))} + child.Env = os.Environ() + child.Env = append(child.Env, listenEnv+"="+strconv.Itoa(len(files))) child.ExtraFiles = files return child } diff --git a/signal.go b/signal.go index c405372..7d99ecc 100644 --- a/signal.go +++ b/signal.go @@ -31,10 +31,11 @@ func handleSignal(env *Environment) { go func() { s := <-ch + delay := getDelaySecondsFromEnv() log.Warn("well: got signal", map[string]interface{}{ "signal": s.String(), + "delay": delay, }) - delay := getDelaySecondsFromEnv() time.Sleep(time.Duration(delay) * time.Second) env.Cancel(errSignaled) }()