Handling Interrupt Signals in Go for a Graceful Shutdown

Handling Interrupt Signals in Go for a Graceful Shutdown

When running a Go program, interrupt signals like Ctrl+C (SIGINT) or kill (SIGTERM) can abruptly terminate the process, potentially leading to data loss or unclean exits. To prevent this, we can catch these signals and perform cleanup before exiting.

Here’s a simple Go program that handles SIGINT, SIGTSTP, SIGTERM, and SIGHUP, ensuring a graceful shutdown:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package main

import (
"fmt"
"os"
"os/signal"
"syscall"
)

func cleanupOperations() {
fmt.Println("Performing cleanup before exit...")
}

func interruptedFunctionResponse(signalData os.Signal) {
fmt.Println("\nReceived Signal:", signalData)

switch signalData {
case syscall.SIGINT:
fmt.Println("Ctrl+C pressed. Exiting gracefully...")
case syscall.SIGTSTP:
fmt.Println("Ctrl+Z pressed. Suspending process...")
case syscall.SIGTERM:
fmt.Println("Termination signal received. Cleaning up...")
case syscall.SIGHUP:
fmt.Println("Terminal closed or Parent process killed. Handling reconnect...")
}

cleanupOperations()
}

func handleInterruptSignals() os.Signal {
waitForSignal := make(chan os.Signal, 1)

signalsToWaitFor := []os.Signal{
syscall.SIGINT, // Ctrl+C
syscall.SIGTSTP, // Ctrl+Z
syscall.SIGTERM, // Kill signal
syscall.SIGHUP, // Terminal closed
}

signal.Notify(waitForSignal, signalsToWaitFor...)

return <-waitForSignal
}

func main() {
fmt.Println("Process running... (Press Ctrl+C to exit, Ctrl+Z to stop)")

gotSignal := handleInterruptSignals()
interruptedFunctionResponse(gotSignal)

fmt.Println("Signal handled. Process exited cleanly.")
}

How It Works

  • The program listens for termination signals using signal.Notify().
  • When a signal is received, it logs the signal, runs cleanup operations, and exits gracefully.

Why It Matters

Without handling signals, the process would terminate abruptly, potentially leaving database connections open or unsaved work lost. Adding a graceful shutdown ensures a smooth exit.

Now, whenever you press Ctrl+C or send a termination signal, your program will handle it properly! 🚀