-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Feat/express graceful shutdown #16156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Feat/express graceful shutdown #16156
Conversation
Override root tsconfig.json exclusion so TypeScript project service finds e2e specs. Also set target, strict, and esModuleInterop compiler options.
Remove leftover debug logging statements to reduce console noise in the adapter.
Pull Request Test Coverage Report for Build c8f84b05-bcfe-45ee-af7b-7f904ed3d19bDetails
💛 - Coveralls |
|
Correct me if i'm wrong but this feels like something that could be implemented outside of the framework's package |
Move isShuttingDown flag activation from dispose() to a new prepareClose() step that runs before callDestroyHook(). This prevents new requests from being processed while providers are being destroyed during shutdown. Add beforeClose() to HttpServer interface and AbstractHttpAdapter so adapters can be notified before the shutdown lifecycle begins.
|
Hi @kamilmysliwiec, thanks for the feedback! You're right that a basic version of this (middleware + flag) can be The key challenge is timing. The shutdown sequence runs:
If the "reject new requests" flag is set externally (e.g., via To fix this properly, the latest commit (a1b82bf) introduces a prepareClose() Additionally, Fastify ships return503OnClosing as a built-in (enabled by Happy to discuss the approach further or adjust anything. |
|
WDYT about renaming this attribute to |
Rename gracefulShutdown to return503OnClosing to align the HTTP option name with Fastify's terminology. The previous name was too vague and could imply broader behavior (connection draining, grace periods) beyond what it actually does.
|
Hi @kamilmysliwiec, your feedback makes sense to me. I have made the required changes. Please have a look. |
|
Hi @kamilmysliwiec, hope you're doing well! I've implemented the rename from gracefulShutdown to return503OnClosing as you suggested — the latest commits reflect that change. Just wanted to check in: are there any other changes or adjustments you'd like me to make? Happy to iterate further if needed. Looking forward to your feedback review when you get a chance. Thanks! |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Currently, when an application shuts down:
By default, the server stops accepting new connections but keeps existing keep-alive connections open indefinitely, potentially hanging the shutdown process (e.g., preventing a Kubernetes pod from terminating).
If forceCloseConnections is set to true, the server destroys all open sockets immediately. This kills in-flight requests, causing clients to experience "socket hang up" or ECONNREFUSED errors.
Issue Number: #11416
What is the new behavior?
This PR adds a gracefulShutdown property to NestApplicationOptions.
When gracefulShutdown: true is enabled (currently implemented for the Express adapter):
Upon calling app.close(), a flag isShuttingDown is set to true.
A middleware intercepts any new requests (even those arriving on existing keep-alive connections) and immediately responds with 503 Service Unavailable and a Connection: close header.
In-flight requests are allowed to proceed and complete naturally.
This allows load balancers and clients to gracefully back off while ensuring no active work is interrupted.
Does this PR introduce a breaking change?
Other information
This implementation follows a pattern similar to Fastify's return503OnClosing option, providing a middle ground between hanging indefinitely and forcefully killing connections.
Verified with a new integration test suite in integration/graceful-shutdown.