Files
hysts 8f6f29260b Fix SSR apps hanging on Ctrl+C at "Stopping Node.js server..." (#13699)
* Fix SSR shutdown hanging on Ctrl+C

With ssr_mode=True, stopping the app printed "Stopping Node.js
server..." and then blocked for 30 seconds, and a second Ctrl+C
during that wait hung the process for good. It needs an app whose
config asks the client for a session heartbeat, so a gr.State, an
unload or stream event, or a per-session cache.

Three problems compounded. The signal handler called
node_process.wait() with no timeout. It also stayed installed while
it ran, so a second signal re-entered it and deadlocked on the
non-reentrant lock Popen._wait() holds across its waitpid() call.
And it left through sys.exit(0) without setting app.stop_event, so
Python kept serving the heartbeat streams that the Node proxy was
waiting on before it could exit.

install_shutdown_handlers() now ignores repeat signals, runs an
on_shutdown callback before touching Node, and stops Node through
stop_node_process(), which kills it if terminate() does not land
within five seconds. Blocks.launch passes _end_streaming_responses
as that callback, so the heartbeats end and Node drains on its own
instead of waiting for its 30 second force-close.

* add changeset

* Harden the SSR shutdown path after self-review

Guard the on_shutdown callback: it sets an asyncio.Event from the main
thread while the loop runs in uvicorn's, so a waiter cancelled mid-set
can raise, and an escaping exception would skip stopping Node and leave
it holding the user-facing port. Ending the streams is only a latency
optimisation; stopping Node is the part that must not be skipped.

Read the served app from server_app rather than app, because queue()
rebinds app but not server_app, so calling queue() after launch() would
point the handler at an App that is not being served.

Assert in the existing startup-ordering test that launch() passes
on_shutdown. The regression this fixes was the missing wiring, and the
other tests all drive node_server in isolation, so dropping that kwarg
would have left every test green.

Also close the child's pipe and reap it in the timeout test, which
otherwise leaks a ResourceWarning.

* Fix SSR Node proxy to scan for a free port by default

Co-authored-by: Cursor <cursoragent@cursor.com>

* changes

* changes

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Abubakar Abid <islamrealm@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
2026-08-04 14:02:02 +09:00
..
2025-03-21 14:15:34 -04:00
2026-06-04 17:53:45 -07:00
2022-05-13 19:48:46 -07:00
2025-12-18 12:28:58 -08:00
2025-09-12 02:27:49 +08:00
2026-07-30 22:56:43 -04:00
2025-11-21 10:57:22 -05:00
2026-02-27 14:01:27 +00:00
2025-09-12 02:27:49 +08:00
2025-11-21 10:57:22 -05:00
2025-05-19 14:45:08 -07:00
2025-11-21 10:57:22 -05:00
2026-07-30 22:56:43 -04:00
2024-12-10 10:52:32 -08:00
2025-12-18 12:28:58 -08:00
2025-11-21 10:57:22 -05:00