Consider this Node.js server code snippet that listens for the SIGINT signal to perform a graceful shutdown. What will be the output when you press Ctrl+C in the terminal?
import http from 'http'; const server = http.createServer((req, res) => { res.end('Hello World'); }); server.listen(3000, () => { console.log('Server running on port 3000'); }); process.on('SIGINT', () => { console.log('SIGINT received, closing server...'); server.close(() => { console.log('Server closed'); process.exit(0); }); });
Think about the order of console logs and when server.close() callback runs.
When SIGINT is received, the handler logs the first message, then calls server.close(). Once the server finishes closing, the callback logs 'Server closed' and exits the process.
You want to convert the server close logic to use async/await with a promise. Which code snippet correctly wraps server.close() in a promise?
import http from 'http'; const server = http.createServer((req, res) => { res.end('Hi'); }); async function shutdown() { // Fill in the correct code here } process.on('SIGTERM', async () => { console.log('SIGTERM received'); await shutdown(); console.log('Shutdown complete'); process.exit(0); });
Remember server.close() uses a callback with an error argument.
Option A correctly wraps server.close() in a promise that resolves on success and rejects on error. Option A is invalid because server.close() does not return a promise. Option A ignores errors. Option A always rejects.
Given this code, why does the server not close when pressing Ctrl+C?
import http from 'http'; const server = http.createServer((req, res) => { res.end('Hello'); }); server.listen(4000); process.on('SIGINT', () => { console.log('SIGINT received'); server.close(); console.log('Server closed'); process.exit(0); });
Think about what happens when process.exit(0) runs immediately after server.close().
The server.close() method is asynchronous. Calling process.exit(0) immediately after it causes the process to exit before the server actually closes. The correct approach is to wait for the server.close() callback before exiting.
Why is implementing graceful shutdown important for Node.js servers?
Think about what happens to active connections when the server closes abruptly.
Graceful shutdown ensures the server stops accepting new requests but finishes processing current ones, avoiding abrupt termination that could cause errors or data loss.
Consider this code snippet. What will be the console output if the process receives SIGINT, then SIGTERM shortly after?
import http from 'http'; const server = http.createServer((req, res) => { res.end('OK'); }); server.listen(5000); let shuttingDown = false; async function shutdown(signal) { if (shuttingDown) { console.log(`Already shutting down on ${signal}`); return; } shuttingDown = true; console.log(`Shutdown started by ${signal}`); await new Promise(resolve => server.close(resolve)); console.log('Server closed'); process.exit(0); } process.on('SIGINT', () => shutdown('SIGINT')); process.on('SIGTERM', () => shutdown('SIGTERM'));
Consider the shuttingDown flag and the order signals are received.
The first signal (SIGINT) triggers shutdown and sets shuttingDown to true. The second signal (SIGTERM) triggers the handler but sees shuttingDown is true, so it logs 'Already shutting down on SIGTERM' and returns. The server closes once, then the process exits.