diff --git a/cli/server.go b/cli/server.go index be2ddab647374..8a6dc99492816 100644 --- a/cli/server.go +++ b/cli/server.go @@ -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) diff --git a/cli/server_test.go b/cli/server_test.go index 369334c48ec14..4066cb1e86ea2 100644 --- a/cli/server_test.go +++ b/cli/server_test.go @@ -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) {