Skip to content

Conversation

@harshcoder-harsh
Copy link

Description

Implements the signal handling improvements proposed in #1705 for better POSIX compliance and systemd compatibility.

Changes

  • SIGINT: Graceful shutdown with double Ctrl+C for force quit
  • SIGTERM: Graceful shutdown with timeout, then SIGKILL (systemd-compatible)
  • SIGQUIT: Immediate termination without cleanup
  • SIGHUP: Default reload signal (replaces SIGUSR2)
  • ⚙️ killTimeout: Configurable timeout for graceful shutdown (default: 10s)
  • 📝 Documentation: Updated README with signal handling behavior and migration notes

Breaking Changes

⚠️ Default signal changed from SIGUSR2 to SIGHUP

Applications listening for SIGUSR2 should either:

  • Update code to listen for SIGHUP (recommended), or
  • Set --signal SIGUSR2 in nodemon configuration

Migration Example

// Old (still works with --signal SIGUSR2)
process.on('SIGUSR2', () => gracefulShutdown());

// New (recommended)
process.on('SIGHUP', () => gracefulShutdown());

Implementation Details

New killWithTimeout() Function

Added a new function that implements graceful shutdown with timeout-based escalation:

  • Sends initial signal to child process
  • Waits for configurable timeout
  • Escalates to SIGKILL if child doesn't exit gracefully
  • Properly manages event listeners and timers

Signal Handler Improvements

  1. SIGINT (Ctrl+C):

    • First press: Graceful shutdown with timeout
    • Second press: Immediate SIGKILL
    • Provides user control over shutdown behavior
  2. SIGTERM:

    • Passes signal to child
    • Waits for killTimeout
    • Escalates to SIGKILL if needed
    • Aligns with systemd's TimeoutStopSec
  3. SIGQUIT (new):

    • Immediate SIGKILL
    • No cleanup
    • For emergency scenarios
  4. SIGHUP (new):

    • Default reload signal
    • Replaces SIGUSR2 for better POSIX compliance

Testing

Manual testing has been performed for:

  • ✅ SIGINT single press (graceful exit)
  • ✅ SIGINT double press (force quit)
  • ✅ SIGTERM with graceful exit
  • ✅ SIGTERM with timeout escalation
  • ✅ SIGQUIT immediate termination
  • ✅ SIGHUP reload
  • ✅ Custom killTimeout configuration

Backward Compatibility

Users can maintain the old behavior by explicitly setting signal: 'SIGUSR2' in their configuration:

nodemon --signal SIGUSR2 server.js

Or in nodemon.json:

{
  \"signal\": \"SIGUSR2\"
}

Related Issues

Fixes #1705
Related to #1667, #1661

Checklist

  • Code follows the project's coding standards
  • Documentation updated
  • Breaking changes documented
  • Commit messages follow conventional commits format
  • Changes are backward compatible (with configuration)

Nodemon Contributor added 2 commits December 3, 2025 23:36
Implements improvements proposed in issue remy#1705:

- Change default signal from SIGUSR2 to SIGHUP for better POSIX compliance
- Add configurable killTimeout option (default: 10000ms)
- Implement graceful SIGINT handling with double Ctrl+C for force quit
- Implement SIGTERM with timeout-based escalation to SIGKILL (systemd-compatible)
- Add SIGQUIT handler for immediate termination without cleanup
- Add SIGHUP handler for reload functionality
- Add killWithTimeout() function for graceful shutdown with escalation

Breaking change: Default signal changed from SIGUSR2 to SIGHUP.
Users can maintain old behavior by setting signal: 'SIGUSR2' in config.

Fixes remy#1705
- Document new signal handling behavior (SIGINT, SIGTERM, SIGQUIT, SIGHUP)
- Add killTimeout configuration documentation
- Update examples to use SIGHUP instead of SIGUSR2
- Add migration notes for users upgrading from older versions

Related to remy#1705
@netlify
Copy link

netlify bot commented Dec 3, 2025

Deploy Preview for nodemon ready!

Name Link
🔨 Latest commit a9b6b75
🔍 Latest deploy log https://app.netlify.com/projects/nodemon/deploys/69308f99b84af90008aeba6c
😎 Deploy Preview https://deploy-preview-2263--nodemon.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@remy
Copy link
Owner

remy commented Dec 3, 2025

There's no tests for this, but more worryingly, you've changed the defaults which would apply a massive blanket change.

I've not really read the AI generated PR description, happy if you want to write your own or summarise it down to a few lines with AI, but I do expect it to be fully tested.

One final point, there's no need for the details that were added to the readme, it's inconsistent with the project style.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Toward a better signal handling

2 participants