/
signals.go
40 lines (33 loc) · 1.05 KB
/
signals.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package cmd
import (
"context"
"os"
"os/signal"
"syscall"
"time"
log "github.com/authzed/spicedb/internal/logging"
)
// SignalContextWithGracePeriod creates a new context that will be cancelled
// when an interrupt/SIGTERM signal is received and the provided grace period
// subsequently finishes.
func SignalContextWithGracePeriod(ctx context.Context, gracePeriod time.Duration) context.Context {
newCtx, cancelfn := context.WithCancel(ctx)
go func() {
signalctx, _ := signal.NotifyContext(newCtx, os.Interrupt, syscall.SIGTERM)
<-signalctx.Done()
log.Ctx(ctx).Info().Msg("received interrupt")
if gracePeriod > 0 {
interruptGrace, _ := signal.NotifyContext(context.Background(), os.Interrupt)
graceTimer := time.NewTimer(gracePeriod)
log.Ctx(ctx).Info().Stringer("timeout", gracePeriod).Msg("starting shutdown grace period")
select {
case <-graceTimer.C:
case <-interruptGrace.Done():
log.Ctx(ctx).Warn().Msg("interrupted shutdown grace period")
}
}
log.Ctx(ctx).Info().Msg("shutting down")
cancelfn()
}()
return newCtx
}