Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6a0f8ae

Browse files
authored
fix: Add SIGHUP and SIGTERM handling to coder server (#3543)
* fix: Add `SIGHUP` and `SIGTERM` handling to `coder server` To prevent additional signals from aborting program execution, signal handling was moved to the beginning of the main function, this ensures that signals stays registered for the entire shutdown procedure. Fixes #1529
1 parent 380022f commit 6a0f8ae

File tree

3 files changed

+38
-11
lines changed

3 files changed

+38
-11
lines changed

cli/server.go

+15-11
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,19 @@ func server() *cobra.Command {
127127
ctx, cancel := context.WithCancel(cmd.Context())
128128
defer cancel()
129129

130+
// Register signals early on so that graceful shutdown can't
131+
// be interrupted by additional signals. Note that we avoid
132+
// shadowing cancel() (from above) here because notifyStop()
133+
// restores default behavior for the signals. This protects
134+
// the shutdown sequence from abrubtly terminating things
135+
// like: database migrations, provisioner work, workspace
136+
// cleanup in dev-mode, etc.
137+
//
138+
// To get out of a graceful shutdown, the user can send
139+
// SIGQUIT with ctrl+\ or SIGKILL with `kill -9`.
140+
notifyCtx, notifyStop := signal.NotifyContext(ctx, interruptSignals...)
141+
defer notifyStop()
142+
130143
// Clean up idle connections at the end, e.g.
131144
// embedded-postgres can leave an idle connection
132145
// which is caught by goleaks.
@@ -521,22 +534,13 @@ func server() *cobra.Command {
521534
// such as via the systemd service.
522535
_ = config.URL().Write(client.URL.String())
523536

524-
// Because the graceful shutdown includes cleaning up workspaces in dev mode, we're
525-
// going to make it harder to accidentally skip the graceful shutdown by hitting ctrl+c
526-
// two or more times. So the stopChan is unlimited in size and we don't call
527-
// signal.Stop() until graceful shutdown finished--this means we swallow additional
528-
// SIGINT after the first. To get out of a graceful shutdown, the user can send SIGQUIT
529-
// with ctrl+\ or SIGTERM with `kill`.
530-
ctx, stop := signal.NotifyContext(ctx, os.Interrupt)
531-
defer stop()
532-
533537
// Currently there is no way to ask the server to shut
534538
// itself down, so any exit signal will result in a non-zero
535539
// exit of the server.
536540
var exitErr error
537541
select {
538-
case <-ctx.Done():
539-
exitErr = ctx.Err()
542+
case <-notifyCtx.Done():
543+
exitErr = notifyCtx.Err()
540544
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Bold.Render(
541545
"Interrupt caught, gracefully exiting. Use ctrl+\\ to force quit",
542546
))

cli/signal_unix.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//go:build !windows
2+
3+
package cli
4+
5+
import (
6+
"os"
7+
"syscall"
8+
)
9+
10+
var interruptSignals = []os.Signal{
11+
os.Interrupt,
12+
syscall.SIGTERM,
13+
syscall.SIGHUP,
14+
}

cli/signal_windows.go

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//go:build windows
2+
3+
package cli
4+
5+
import (
6+
"os"
7+
)
8+
9+
var interruptSignals = []os.Signal{os.Interrupt}

0 commit comments

Comments
 (0)