feat: make it harder to skip graceful shutdown accidentally (#1327)

* feat: make it harder to skip graceful shutdown accidentally

Signed-off-by: Spike Curtis <spike@coder.com>

* fixup: don't use unbuffered signal channel

Signed-off-by: Spike Curtis <spike@coder.com>
This commit is contained in:
Spike Curtis
2022-05-06 13:45:18 -07:00
committed by GitHub
parent 00806580f5
commit ad8d9dd71a
2 changed files with 15 additions and 2 deletions
+9 -2
View File
@@ -342,6 +342,12 @@ func server() *cobra.Command {
return xerrors.Errorf("notify systemd: %w", err)
}
// Because the graceful shutdown includes cleaning up workspaces in dev mode, we're
// going to make it harder to accidentally skip the graceful shutdown by hitting ctrl+c
// two or more times. So the stopChan is unlimited in size and we don't call
// signal.Stop() until graceful shutdown finished--this means we swallow additional
// SIGINT after the first. To get out of a graceful shutdown, the user can send SIGQUIT
// with ctrl+\ or SIGTERM with `kill`.
stopChan := make(chan os.Signal, 1)
defer signal.Stop(stopChan)
signal.Notify(stopChan, os.Interrupt)
@@ -358,12 +364,13 @@ func server() *cobra.Command {
return err
case <-stopChan:
}
signal.Stop(stopChan)
_, err = daemon.SdNotify(false, daemon.SdNotifyStopping)
if err != nil {
return xerrors.Errorf("notify systemd: %w", err)
}
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "\n\n"+cliui.Styles.Bold.Render("Interrupt caught. Gracefully exiting..."))
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "\n\n"+
cliui.Styles.Bold.Render(
"Interrupt caught, gracefully exiting. Use ctrl+\\ to force quit"))
if dev {
organizations, err := client.OrganizationsByUser(cmd.Context(), codersdk.Me)
+6
View File
@@ -271,6 +271,12 @@ func TestServer(t *testing.T) {
require.NoError(t, err)
err = currentProcess.Signal(os.Interrupt)
require.NoError(t, err)
// Send a two more signal, which should be ignored. Send 2 because the channel has a buffer
// of 1 and we want to make sure that nothing strange happens if we exceed the buffer.
err = currentProcess.Signal(os.Interrupt)
require.NoError(t, err)
err = currentProcess.Signal(os.Interrupt)
require.NoError(t, err)
<-done
})
t.Run("DatadogTracerNoLeak", func(t *testing.T) {