[Bugfix] Fix launch render hanging on shutdown (#54913)
Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Chauncey committed
Sep 2, 2026 at 16:15 UTC
b2558f8da330a2fde6de44ea128d3c23c5cf8268
1 file changed
+22
-15
vllm/entrypoints/launchers/launcher.py
+22
-15
@@ -102,7 +102,12 @@ async def serve_http(
102
103
loop = asyncio.get_running_loop()
104
105
- watchdog_task = loop.create_task(watchdog_loop(server, app.state.engine_client))
105
+ engine_client = app.state.engine_client
106
+ watchdog_task = (
107
+ loop.create_task(watchdog_loop(server, engine_client))
108
+ if engine_client is not None
109
+ else None
110
+ )
111
server_task = loop.create_task(server.serve(sockets=[sock] if sock else None))
112
113
ssl_cert_refresher = (
@@ -133,25 +138,26 @@ async def serve_http(
138
async def handle_shutdown() -> None:
139
await shutdown_event.wait()
140
136
- engine_client = app.state.engine_client
137
- timeout = engine_client.vllm_config.shutdown_timeout
138
- mode = "abort" if timeout == 0 else "drain"
141
+ if engine_client is not None:
142
+ timeout = engine_client.vllm_config.shutdown_timeout
143
+ mode = "abort" if timeout == 0 else "drain"
144
140
- logger.info(
141
- "[shutdown] API server: stopping engine client mode=%s timeout=%ss",
142
- mode,
143
- timeout,
144
- )
145
+ logger.info(
146
+ "[shutdown] API server: stopping engine client mode=%s timeout=%ss",
147
+ mode,
148
+ timeout,
149
+ )
150
146
- await loop.run_in_executor(
147
- None, partial(engine_client.shutdown, timeout=timeout)
148
- )
149
- logger.info_once("[shutdown] API server: engine client stopped")
151
+ await loop.run_in_executor(
152
+ None, partial(engine_client.shutdown, timeout=timeout)
153
+ )
154
+ logger.info_once("[shutdown] API server: engine client stopped")
155
156
server.should_exit = True
157
logger.info_once("[shutdown] API server: signalling HTTP server shutdown")
158
server_task.cancel()
154
- watchdog_task.cancel()
159
+ if watchdog_task is not None:
160
+ watchdog_task.cancel()
161
if ssl_cert_refresher:
162
ssl_cert_refresher.stop()
163
@@ -174,7 +180,8 @@ async def serve_http(
180
return server.shutdown()
181
finally:
182
shutdown_task.cancel()
177
- watchdog_task.cancel()
183
+ if watchdog_task is not None:
184
+ watchdog_task.cancel()
185
186
187
async def watchdog_loop(server: uvicorn.Server, engine: EngineClient):