📖 Scenario: You are building a simple Node.js server that needs to stop cleanly when the application is closed or restarted. This means it should finish any ongoing work and close resources properly before exiting.
🎯 Goal: Create a Node.js server that listens on port 3000 and handles shutdown signals gracefully by closing the server and logging a message before the program exits.
📋 What You'll Learn
Create a basic HTTP server using Node.js
Add a variable to track if the server is running
Implement a listener for shutdown signals like SIGINT
Close the server gracefully and log a shutdown message
💡 Why This Matters
🌍 Real World
Graceful shutdown is important for servers to close connections and free resources properly before stopping, avoiding data loss or corruption.
💼 Career
Many backend developer roles require knowledge of handling process signals and graceful shutdown to build reliable and maintainable server applications.
Progress0 / 4 steps
1
Create a basic HTTP server
Create a Node.js HTTP server using http.createServer that responds with 'Hello World' to any request. Make the server listen on port 3000.
Node.js
Hint
Use http.createServer to create the server and server.listen(3000) to start it.
2
Add a running state variable
Add a variable called isRunning and set it to true to track if the server is currently running.
Node.js
Hint
Declare let isRunning = true; after starting the server.
3
Listen for shutdown signals
Add a listener for the 'SIGINT' signal using process.on. Inside the listener, set isRunning to false and call server.close() to stop the server.
Node.js
Hint
Use process.on('SIGINT', () => { ... }) to listen for the shutdown signal.
4
Log shutdown completion
Add a listener for the server's 'close' event. Inside it, log 'Server has shut down gracefully.' and call process.exit(0) to exit the program cleanly.
Node.js
Hint
Use server.on('close', () => { ... }) to handle the server closing event.
Practice
(1/5)
1. What is the main purpose of graceful shutdown in a Node.js application?
easy
A. To stop the app safely without losing data or leaving tasks unfinished
B. To restart the app automatically after a crash
C. To speed up the app startup time
D. To increase the app's memory usage
Solution
Step 1: Understand graceful shutdown concept
Graceful shutdown means stopping the app carefully so it finishes ongoing work and saves data.
Step 2: Identify the purpose in options
Only To stop the app safely without losing data or leaving tasks unfinished describes stopping safely without losing data or leaving tasks unfinished.
Final Answer:
To stop the app safely without losing data or leaving tasks unfinished -> Option A
Quick Check:
Graceful shutdown = safe stop without data loss [OK]
Hint: Graceful shutdown means stopping safely, not restarting or speeding up [OK]
Common Mistakes:
Confusing graceful shutdown with app restart
Thinking it improves startup speed
Assuming it increases memory usage
2. Which Node.js code snippet correctly listens for the SIGINT signal to start graceful shutdown?
easy
A. process.on('SIGTERM', () => { console.log('Shutting down'); });
B. process.listen('SIGINT', () => { console.log('Shutting down'); });
C. process.on('SIGINT', () => { console.log('Shutting down'); process.exit(); });
D. process.signal('SIGINT', () => { console.log('Shutting down'); });
Solution
Step 1: Recall correct event listener syntax
Node.js uses process.on('signal', callback) to listen for signals like SIGINT.
Step 2: Check options for correct syntax and signal
process.on('SIGINT', () => { console.log('Shutting down'); process.exit(); }); uses process.on with 'SIGINT' and a callback, which is correct. process.on('SIGTERM', () => { console.log('Shutting down'); }); uses SIGTERM, which is valid but not SIGINT as asked. Options B and D use invalid methods.
A. process.exit(0) runs before server.close finishes, causing abrupt exit
B. SIGINT event is not supported by process
C. console.log should be before server.close
D. server.close() does not exist on http server
Solution
Step 1: Understand asynchronous server.close
server.close() is asynchronous and takes a callback to run after closing.
Step 2: Identify order of commands
Here, process.exit(0) runs immediately after server.close() call, not waiting for close to finish, causing abrupt exit.
Final Answer:
process.exit(0) runs before server.close finishes, causing abrupt exit -> Option A
Quick Check:
Wait for server.close callback before exiting [OK]
Hint: Always exit inside server.close callback to wait for close [OK]
Common Mistakes:
Calling process.exit too early
Thinking SIGINT is unsupported
Misunderstanding server.close existence
5. You want to handle both SIGINT and SIGTERM signals to gracefully shutdown your Node.js app. Which code correctly ensures the server closes once and exits safely without duplicate calls?
D. let isShuttingDown = false;
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
function shutdown() {
if (isShuttingDown) return;
isShuttingDown = true;
server.close(() => {
console.log('Closed');
process.exit(0);
});
}
Solution
Step 1: Understand multiple signal handling
Both SIGINT and SIGTERM can trigger shutdown, so we must avoid running shutdown twice.
Step 2: Check for duplicate shutdown prevention
let isShuttingDown = false;
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
function shutdown() {
if (isShuttingDown) return;
isShuttingDown = true;
server.close(() => {
console.log('Closed');
process.exit(0);
});
} uses a flag isShuttingDown to run shutdown only once, preventing duplicate server.close and exit calls.