Graceful Shutdown with Signal Handling in Go
Signal handling is crucial for building robust and responsive applications. This challenge asks you to implement a Go program that gracefully shuts down when it receives a specific signal (SIGINT - Ctrl+C). This is essential for cleaning up resources, saving state, and preventing data loss before exiting.
Problem Description
You need to create a Go program that listens for the SIGINT signal (typically triggered by pressing Ctrl+C). Upon receiving this signal, the program should:
- Print a message indicating that it received the signal and is shutting down gracefully.
- Wait for a specified duration (e.g., 5 seconds) to allow for cleanup operations.
- After the cleanup duration, exit the program with a status code of 0.
The program should continue to run and perform some dummy work (e.g., printing a message every second) until the SIGINT signal is received. The cleanup duration should be configurable.
Key Requirements:
- Use the
os/signalpackage to register a signal handler for SIGINT. - Implement a cleanup function that simulates resource cleanup (e.g., closing files, database connections). This function doesn't need to actually perform any real cleanup, just print a message indicating it's happening.
- Use a
time.Sleepto simulate the cleanup duration. - Handle the signal gracefully, preventing abrupt termination.
Expected Behavior:
The program should run indefinitely, printing messages. When Ctrl+C is pressed, the program should print a shutdown message, then execute the cleanup function, wait for the specified duration, and finally exit cleanly.
Edge Cases to Consider:
- What happens if the program receives the signal multiple times? (The handler should only execute once).
- How to handle potential errors during cleanup (though error handling is not strictly required for this challenge, consider how it could be handled).
Examples
Example 1:
Input: Program running, user presses Ctrl+C
Output:
"Received SIGINT. Starting graceful shutdown...\n"
"Performing cleanup...\n"
(5 seconds pass)
"Exiting...\n"
Explanation: The program receives SIGINT, prints a shutdown message, simulates cleanup, waits 5 seconds, and then exits.
Example 2:
Input: Program running, user presses Ctrl+C multiple times
Output:
"Received SIGINT. Starting graceful shutdown...\n"
"Performing cleanup...\n"
(5 seconds pass)
"Exiting...\n"
Explanation: Even though SIGINT is received multiple times, the shutdown process only executes once.
Constraints
- The cleanup duration should be configurable via a constant (e.g.,
const cleanupDuration = 5 * time.Second). - The program must exit with a status code of 0 upon graceful shutdown.
- The program should not panic or crash due to signal handling.
- The cleanup function should simulate cleanup by printing a message. No actual resource cleanup is required.
Notes
- The
signal.Notifyfunction is the primary tool for registering signal handlers in Go. - Consider using a
context.Contextto manage the shutdown process more effectively in a real-world application. However, for this simplified challenge, a simpletime.Sleepis sufficient. - Think about how you would ensure that only one shutdown process is initiated, even if multiple signals are received. A simple flag can be used to prevent re-entry into the shutdown handler.