Skip to content

Commit e917f2c

Browse files
committed
cmd: handle signals via NotifyContext
Install a single signal.NotifyContext in main and let the HTTP and SMTP servers register a context.AfterFunc that shuts them down when the shared context is cancelled, instead of each wiring up its own os/signal channel. This drops the duplicated signal plumbing. Derive the shutdown timeout from a fresh background context. The signal already cancels the parent context, so reusing it as the timeout parent would make the graceful shutdown deadline expire immediately. Signed-off-by: Robin Jarry <robin@jarry.cc>
1 parent 75d5387 commit e917f2c

3 files changed

Lines changed: 27 additions & 38 deletions

File tree

‎cmd/pw/http/main.go‎

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ package http
77

88
import (
99
"context"
10+
"errors"
1011
"fmt"
1112
"net"
1213
"net/http"
13-
"os"
14-
"os/signal"
15-
"syscall"
1614
"time"
1715

1816
"github.com/getpatchwork/patchwork/cmd/pw/pw"
@@ -57,26 +55,21 @@ func (c *CLI) Run(ctx context.Context) error {
5755
return fmt.Errorf("listen: %w", err)
5856
}
5957

60-
done := make(chan os.Signal, 1)
61-
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
58+
log.Noticef("patchwork %s listening on http://%s", version, sock.Addr())
6259

63-
go func() {
64-
log.Noticef("patchwork %s listening on http://%s", version, sock.Addr())
65-
if e := srv.Serve(sock); e != nil && e != http.ErrServerClosed {
66-
err = fmt.Errorf("serve: %w", e)
67-
done <- syscall.SIGCHLD
68-
}
69-
}()
70-
71-
sig := <-done
72-
if sig != syscall.SIGCHLD {
73-
log.Noticef("received signal %v, shutting down", sig)
74-
timeout, cancel := context.WithTimeout(ctx, 30*time.Second)
60+
unregister := context.AfterFunc(ctx, func() {
61+
log.Noticef("%s, shutting down", context.Cause(ctx))
62+
timeout, cancel := context.WithTimeout(context.Background(), 30*time.Second)
7563
defer cancel()
7664
if e := srv.Shutdown(timeout); e != nil {
77-
err = fmt.Errorf("shutdown: %w", e)
65+
log.Errorf("shutdown: %v", e)
7866
}
67+
})
68+
defer unregister()
69+
70+
if err = srv.Serve(sock); err != nil && !errors.Is(err, http.ErrServerClosed) {
71+
return fmt.Errorf("serve: %w", err)
7972
}
8073

81-
return err
74+
return nil
8275
}

‎cmd/pw/ingress/main.go‎

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ import (
1313
"io"
1414
"net"
1515
"os"
16-
"os/signal"
1716
"strings"
18-
"syscall"
1917
"time"
2018

2119
"github.com/emersion/go-mbox"
@@ -87,28 +85,23 @@ func (c *CLI) Run(ctx context.Context) error {
8785
return fmt.Errorf("smtp: %w", err)
8886
}
8987

90-
done := make(chan os.Signal, 1)
91-
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
88+
log.Noticef("patchwork %s listening on smtp://%s", pw.GetVersion(ctx), sock.Addr())
9289

93-
go func() {
94-
log.Noticef("patchwork %s listening on smtp://%s", pw.GetVersion(ctx), sock.Addr())
95-
if e := srv.Serve(sock); e != nil && !errors.Is(e, net.ErrClosed) {
96-
err = fmt.Errorf("serve: %w", e)
97-
done <- syscall.SIGCHLD
98-
}
99-
}()
100-
101-
sig := <-done
102-
if sig != syscall.SIGCHLD {
103-
log.Noticef("received signal %v, shutting down", sig)
104-
timeout, cancel := context.WithTimeout(ctx, 30*time.Second)
90+
unregister := context.AfterFunc(ctx, func() {
91+
log.Noticef("%s, shutting down", context.Cause(ctx))
92+
timeout, cancel := context.WithTimeout(context.Background(), 30*time.Second)
10593
defer cancel()
10694
if e := srv.Shutdown(timeout); e != nil {
107-
err = fmt.Errorf("shutdown: %w", e)
95+
log.Errorf("shutdown: %v", e)
10896
}
97+
})
98+
defer unregister()
99+
100+
if err = srv.Serve(sock); err != nil && !errors.Is(err, net.ErrClosed) {
101+
return fmt.Errorf("serve: %w", err)
109102
}
110103

111-
return err
104+
return nil
112105
}
113106

114107
func (c *CLI) startSMTPServer(ctx context.Context) (net.Listener, *smtp.Server, error) {

‎cmd/pw/main.go‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ package main
88
import (
99
"context"
1010
"fmt"
11+
"os/signal"
1112
"runtime"
1213
"strings"
14+
"syscall"
1315

1416
"github.com/alecthomas/kong"
1517

@@ -63,7 +65,8 @@ func main() {
6365
k.Stderr = log.ErrLogger().Writer()
6466
}
6567

66-
ctx := context.Background()
68+
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
69+
defer stop()
6770
ctx = pw.WithConfig(ctx, &cli.Config)
6871
ctx = pw.WithVersion(ctx, Version)
6972

0 commit comments

Comments
 (0)