Update signals example to use signal.NotifyContext

This commit is contained in:
An Yu 2021-08-06 16:09:13 -04:00
parent 58e66a8103
commit 364b41fdea
2 changed files with 16 additions and 26 deletions

View File

@ -8,8 +8,8 @@
package main package main
import ( import (
"context"
"fmt" "fmt"
"os"
"os/signal" "os/signal"
"syscall" "syscall"
) )
@ -17,30 +17,21 @@ import (
func main() { func main() {
// Go signal notification works by sending `os.Signal` // Go signal notification works by sending `os.Signal`
// values on a channel. We'll create a channel to // values on a channel.
// receive these notifications (we'll also make one to
// notify us when the program can exit).
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
// `signal.Notify` registers the given channel to // `signal.NotifyContext` registers a channel under the hood to receive
// receive notifications of the specified signals. // notifications of the specified signals.
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) // When a specified signal is received, it returns a context with a closed Done channel.
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
// This goroutine executes a blocking receive for // The program will wait here until the returned context's Done channel is closed.
// signals. When it gets one it'll print it out // A graceful exit can then be handled before the deferred stop is executed.
// and then notify the program that it can finish. // `stop` restores the default behavior of the signal (e.g., exiting on SIGINT)
go func() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()
// The program will wait here until it gets the
// expected signal (as indicated by the goroutine
// above sending a value on `done`) and then exit.
fmt.Println("awaiting signal") fmt.Println("awaiting signal")
<-done <-ctx.Done()
fmt.Println("exiting") fmt.Println("exiting gracefully")
// Note: For cases where decisions based on which signal was received are needed,
// `signal.Notify` and `context.WithCancel` can be used together instead.
} }

View File

@ -1,9 +1,8 @@
# When we run this program it will block waiting for a # When we run this program it will block waiting for a
# signal. By typing `ctrl-C` (which the # signal. By typing `ctrl-C` (which the
# terminal shows as `^C`) we can send a `SIGINT` signal, # terminal shows as `^C`) we can send a `SIGINT` signal,
# causing the program to print `interrupt` and then exit. # causing the program to print `exiting gracefully` and then exit.
$ go run signals.go $ go run signals.go
awaiting signal awaiting signal
^C ^C
interrupt
exiting exiting