...
1 package shutdown
2
3 import (
4 "context"
5 "net/http"
6 "os"
7 "os/signal"
8 "time"
9
10 syscall "golang.org/x/sys/unix"
11
12 "edge-infra.dev/pkg/lib/logging"
13 )
14
15 type Graceful struct {
16 term chan os.Signal
17 fail chan error
18 logger *logging.EdgeLogger
19 }
20
21 func NewGraceful() *Graceful {
22 return &Graceful{
23 term: make(chan os.Signal),
24 fail: make(chan error),
25 logger: logging.NewLogger(),
26 }
27 }
28
29
30 func (g *Graceful) Serve(doWork func() error, teardown func(context.Context) error) error {
31 go func() {
32 signal.Notify(g.term, syscall.SIGINT, syscall.SIGTERM)
33 <-g.term
34
35
36 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
37 defer cancel()
38
39
40 g.fail <- teardown(ctx)
41 }()
42
43
44 if err := doWork(); err != nil && err != http.ErrServerClosed {
45 g.logger.Error(err, "doWork had an error")
46 return err
47 }
48
49
50 return <-g.fail
51 }
52
View as plain text