Bird
Raised Fist0
Node.jsframework~20 mins

Graceful shutdown handling in Node.js - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Graceful Shutdown Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What happens when the server receives SIGINT?

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?

Node.js
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);
  });
});
AServer running on port 3000\nServer closed\nSIGINT received, closing server...
BServer running on port 3000\nSIGINT received, closing server...\n(process hangs, no further output)
CServer running on port 3000\nSIGINT received, closing server...\nServer closed
DServer running on port 3000\n(process exits immediately without logs)
Attempts:
2 left
💡 Hint

Think about the order of console logs and when server.close() callback runs.

📝 Syntax
intermediate
2:00remaining
Which option correctly handles server close with async/await?

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?

Node.js
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);
});
Aawait new Promise((resolve, reject) => server.close(err => err ? reject(err) : resolve()));
Bawait server.close();
Cawait new Promise(resolve => server.close(resolve));
Dawait new Promise((resolve, reject) => server.close(() => reject()));
Attempts:
2 left
💡 Hint

Remember server.close() uses a callback with an error argument.

🔧 Debug
advanced
2:00remaining
Why does the server not close on SIGINT?

Given this code, why does the server not close when pressing Ctrl+C?

Node.js
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);
});
ABecause the SIGINT event is not properly registered.
BBecause <code>server.close()</code> is asynchronous and the process exits before it finishes closing.
CBecause <code>server.close()</code> requires a callback to close the server.
DBecause the server never started listening.
Attempts:
2 left
💡 Hint

Think about what happens when process.exit(0) runs immediately after server.close().

🧠 Conceptual
advanced
1:30remaining
What is the main benefit of graceful shutdown in Node.js servers?

Why is implementing graceful shutdown important for Node.js servers?

AIt improves server startup speed by caching modules.
BIt automatically restarts the server after it crashes.
CIt disables all incoming connections immediately to save resources.
DIt allows the server to finish handling ongoing requests before closing, preventing data loss or errors.
Attempts:
2 left
💡 Hint

Think about what happens to active connections when the server closes abruptly.

❓ state_output
expert
2:30remaining
What is the output order when multiple shutdown signals are received?

Consider this code snippet. What will be the console output if the process receives SIGINT, then SIGTERM shortly after?

Node.js
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'));
AShutdown started by SIGINT\nAlready shutting down on SIGTERM\nServer closed
BShutdown started by SIGTERM\nAlready shutting down on SIGINT\nServer closed
CShutdown started by SIGINT\nServer closed
DShutdown started by SIGINT\nServer closed\nShutdown started by SIGTERM
Attempts:
2 left
💡 Hint

Consider the shuttingDown flag and the order signals are received.

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

  1. Step 1: Understand graceful shutdown concept

    Graceful shutdown means stopping the app carefully so it finishes ongoing work and saves data.
  2. 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.
  3. Final Answer:

    To stop the app safely without losing data or leaving tasks unfinished -> Option A
  4. 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

  1. Step 1: Recall correct event listener syntax

    Node.js uses process.on('signal', callback) to listen for signals like SIGINT.
  2. 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.
  3. Final Answer:

    process.on('SIGINT', () => { console.log('Shutting down'); process.exit(); }); -> Option C
  4. Quick Check:

    Use process.on('SIGINT', callback) for SIGINT [OK]
Hint: Use process.on('SIGINT', callback) to handle Ctrl+C [OK]
Common Mistakes:
  • Using process.listen instead of process.on
  • Using process.signal which does not exist
  • Confusing SIGINT with SIGTERM
3. Consider this code snippet:
const http = require('http');
const server = http.createServer((req, res) => {
  res.end('Hello');
});

process.on('SIGINT', () => {
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });
});

server.listen(3000);
What happens when you press Ctrl+C in the terminal?
medium
A. The server immediately exits without closing connections
B. The server stops accepting new connections, logs 'Server closed', then exits
C. The server ignores Ctrl+C and keeps running
D. The server crashes with an error

Solution

  1. Step 1: Understand SIGINT handler

    The code listens for SIGINT (Ctrl+C), then calls server.close to stop new connections and waits for existing ones to finish.
  2. Step 2: Analyze server.close callback

    When server.close finishes, it logs 'Server closed' and calls process.exit(0) to exit cleanly.
  3. Final Answer:

    The server stops accepting new connections, logs 'Server closed', then exits -> Option B
  4. Quick Check:

    Ctrl+C triggers server.close then exit [OK]
Hint: SIGINT triggers server.close callback before exit [OK]
Common Mistakes:
  • Thinking server exits immediately without closing
  • Assuming Ctrl+C is ignored
  • Expecting a crash error
4. This code aims to handle graceful shutdown but has a bug:
process.on('SIGINT', () => {
  server.close();
  console.log('Server closed');
  process.exit(0);
});
What is the problem?
medium
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

  1. Step 1: Understand asynchronous server.close

    server.close() is asynchronous and takes a callback to run after closing.
  2. 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.
  3. Final Answer:

    process.exit(0) runs before server.close finishes, causing abrupt exit -> Option A
  4. 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?
hard
A. process.on('SIGINT', () => server.close(() => process.exit(0))); process.on('SIGTERM', () => server.close(() => process.exit(0)));
B. process.on('SIGINT', () => { console.log('Shutting down'); }); process.on('SIGTERM', () => { console.log('Shutting down'); });
C. process.on('SIGINT', () => { server.close(); process.exit(0); }); process.on('SIGTERM', () => { server.close(); process.exit(0); });
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

  1. Step 1: Understand multiple signal handling

    Both SIGINT and SIGTERM can trigger shutdown, so we must avoid running shutdown twice.
  2. 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.
  3. Step 3: Analyze other options

    process.on('SIGINT', () => server.close(() => process.exit(0))); process.on('SIGTERM', () => server.close(() => process.exit(0))); calls server.close twice if both signals arrive. process.on('SIGINT', () => { server.close(); process.exit(0); }); process.on('SIGTERM', () => { server.close(); process.exit(0); }); calls process.exit immediately without waiting. process.on('SIGINT', () => { console.log('Shutting down'); }); process.on('SIGTERM', () => { console.log('Shutting down'); }); only logs without closing.
  4. Final Answer:

    Code with a flag to prevent duplicate shutdown and safely close server once -> Option D
  5. Quick Check:

    Use a flag to avoid duplicate shutdown calls [OK]
Hint: Use a flag to run shutdown logic only once for multiple signals [OK]
Common Mistakes:
  • Calling server.close multiple times causing errors
  • Exiting process before server closes
  • Not handling both signals properly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard