From 5561c4bb48fe44ee9d38593356cda91c9058ca70 Mon Sep 17 00:00:00 2001 From: YuJack Date: Tue, 6 Sep 2022 00:06:13 +0800 Subject: [PATCH] feat: add other-graceful --- README.md | 8 ++++- other/01-graceful/README.md | 10 ++++++ other/01-graceful/main.go | 66 +++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 other/01-graceful/README.md create mode 100644 other/01-graceful/main.go diff --git a/README.md b/README.md index 2629a40..bb79de9 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,10 @@ | 1 | [Generator](./01-generator) | | 2 | [Fan-In](./02-fan-in) | | 3 | [Fan-Out](./03-fan-out) | -| 4 | [Fan-In and Fan-Out](./04-fan-in-fan-out) | +| 4 | [Fan-In and Fan-Out](./04-fan-in-fan-out) | + +# 其他相關使用 + +| Number | Name | +|--------|------------------------------------------| +| 1 | [Graceful Shutdown](./other/01-graceful) | \ No newline at end of file diff --git a/other/01-graceful/README.md b/other/01-graceful/README.md new file mode 100644 index 0000000..b08d51a --- /dev/null +++ b/other/01-graceful/README.md @@ -0,0 +1,10 @@ +# Graceful Shutdown + +通常應用程式在接受到 `kill -9` `kill -15` 等等相關訊號會直接關閉,但是實際上可以透過程式去處理取得這些 `signal` 時,要怎麼安全地關閉應用程式。 + + +參考 [Graceful Shutdown Example Code](./main.go) + +在範例程式中,可以試著換成 `newNormalContext`,並且在印出 0 的時候去中斷程式,會看到使用 `newNormalContext` 時並不會看到 1 被印出來,就意外的被中斷。 + +但是當使用 `newGracefulContext` 接收 signal 的情況下,可以做一些後續收尾的動作。所以用這個 `newGracefulContext` 看到 0 的時候去中斷程式,會看到 1 被印出來。 \ No newline at end of file diff --git a/other/01-graceful/main.go b/other/01-graceful/main.go new file mode 100644 index 0000000..c909393 --- /dev/null +++ b/other/01-graceful/main.go @@ -0,0 +1,66 @@ +package main + +import ( + "context" + "fmt" + "os" + "os/signal" + "sync" + "time" +) + +func newNormalContext() context.Context { + return context.Background() +} + +func newGracefulContext() context.Context { + ctx, cancel := context.WithCancel(context.Background()) + + go func() { + sig := make(chan os.Signal) + signal.Notify(sig) // accept all signal + defer signal.Stop(sig) + + select { + case <-ctx.Done(): + case <-sig: + cancel() + } + + fmt.Println("graceful shutdown") + }() + + return ctx +} + +func main() { + wg := sync.WaitGroup{} + wg.Add(1) + + ctx := newGracefulContext() + //ctx := newNormalContext() + go func(ctx context.Context) { + defer wg.Done() + + data := 0 + fmt.Println(data) + + // simulate the hard work, then set data of 1 + time.Sleep(2 * time.Second) + data = 1 + fmt.Println(data) + + select { + case <-ctx.Done(): + fmt.Println("skip following job") + return + default: + } + + time.Sleep(2 * time.Second) + data = 2 + fmt.Println(data) + }(ctx) + + wg.Wait() +}