stoppable

repository·master·Indexed 19 days ago

https://github.com/hunterloftis/stoppable

A Node.js utility for version 1.1.0 that enhances standard server.close() behavior for HTTP and HTTPS servers. It adds a .stop() method to server instances, allowing them to stop accepting new connections and close idle keep-alive connections while ensuring in-flight requests are completed. It supports an optional grace period in milliseconds to force-close remaining connections if they do not finish within the specified timeframe.

Tokens
1.5K
Snippets
6
Records
7
Agent score
15%

What's inside stoppable

  1. How Stoppable manages connection shutdown

    master

    Stoppable solves the issue where Node's default server.close() might not handle idle keep-alive connections as expected.

    Key Behaviors:

    • New Connections: Immediately stops accepting new connections.
    • Idle Connections: Closes existing idle connections (including keep-alives).
    • In-flight Requests: Does not kill requests that are currently being processed.
    • Shutdown Mechanism: Instead of simply destroying sockets, it attempts to handle clients respectfully by sending FIN packets first.
    • Grace Period: If a grace period is provided during initialization, Stoppable will wait that many milliseconds before force-closing any remaining connections.
  2. Wrap an HTTP/HTTPS server with stoppable()

    master

    To use Stoppable, pass an existing HTTP or HTTPS server instance to the stoppable() function. This decorates the server instance with a new .stop() method.

    Arguments:

    • server: Any HTTP or HTTPS Server instance.
    • grace (optional): Milliseconds to wait before force-closing connections. Defaults to Infinity (no force-close). Use 0 to immediately kill all sockets.
    const http = require('http');
    const stoppable = require('stoppable');
    
    const server = stoppable(http.createServer(handler), 5000);
    // The server now has a .stop() method and can be used normally
  3. Stop the server gracefully with stop()

    master

    The .stop(callback) method stops the server from accepting new connections and closes existing, idle connections (including keep-alives) without killing in-flight requests.

    Arguments:

    • callback (optional): A function called when the server has stopped. It follows the standard Node.js error-first pattern but includes a second argument indicating if the stop was graceful.

    Callback Signature: (err, wasGraceful) => void

    • err: The error object, if any.
    • wasGraceful: A boolean indicating whether the server stopped gracefully.
    server.stop((err, wasGraceful) => {
      if (err) console.error('Stop failed:', err);
      if (wasGraceful) {
        console.log('Server stopped gracefully');
      } else {
        console.log('Server was force-closed');
      }
    });
  4. Configure the grace period for graceful shutdown

    master

    When calling the stoppable function, you can provide an optional second argument to define how long the server should wait for requests to finish before forcing a shutdown.

    • grace (Number): The time in milliseconds to wait before forcefully destroying all connections.
    • If grace is undefined, the server waits indefinitely (Infinity).
    // Wait indefinitely
    stoppable(server);
    
    // Wait for 10 seconds before forcing shutdown
    stoppable(server, 10000);
  5. Decorate an HTTP/HTTPS server with stop()

    master

    The stoppable module provides a way to add a graceful shutdown method to an existing Node.js http.Server or https.Server instance.

    When you wrap a server with stoppable, it adds a .stop(callback) method. Calling this method prevents new connections from being accepted and waits for existing requests to finish before closing the sockets.

    If a grace period (in milliseconds) is provided, the server will force-close all connections after that time has elapsed. If no grace period is provided, it will wait indefinitely for requests to finish.

    const stoppable = require('stoppable');
    const http = require('http');
    
    const server = http.createServer((req, res) => {
      res.end('hello');
    });
    
    // Decorate the server with the stop method
    // Optional: pass a grace period in milliseconds
    stoppable(server, 5000);
    
    server.listen(3000);
    
    // Later, to shut down gracefully:
    server.stop((err, gracefully) => {
      if (err) console.error('Error during stop:', err);
      if (gracefully) {
        console.log('Server stopped gracefully');
      } else {
        console.log('Server stopped after grace period expired');
      }
    });
  6. Use the server.stop(callback) method

    master

    The .stop(callback) method initiates the graceful shutdown process.

    Behavior:

    1. It sets an internal stopped flag to true, preventing new requests from being processed.
    2. It calls server.close(), which stops the server from accepting new connections.
    3. It tracks active requests per socket. Once a socket has zero pending requests, the socket is ended.
    4. If a grace period was configured, it will trigger destroyAll() after the timeout, which forcefully closes and then destroys all remaining sockets.

    Callback Arguments:

    • err: An error object if server.close() encountered an error.
    • gracefully: A boolean indicating if the server shut down gracefully (true) or if it was forced to shut down due to the grace period expiring (false).
    server.stop((err, gracefully) => {
      // err: Error or null
      // gracefully: boolean
    });