[Bugfix] Fix colocate-async sleep admission race and deliver AR abort tokens (#6367)

Signed-off-by: knlnguyen1802 <knlnguyen1802@gmail.com>
Signed-off-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Samit <285365963@qq.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Samit <285365963@qq.com>
This commit is contained in:
authored and GitHub committed 2026-08-29 09:11:39 +00:00
1 parent 5c47fd0bc8
commit bb5bf8fd0a
23 files changed
+1229 -157

No files matched your search

+63 -8
View File
@@ -871,14 +871,19 @@ class Orchestrator:
When ``msg.rpc_id`` is set, emit :class:`AbortResultMessage` after
stage aborts, binding release, and request cleanup complete so the
caller can await acknowledgment. Fire-and-forget aborts omit rpc_id.
AR final-stage abort outputs (partial tokens) are attached to the
result message when ``rpc_id`` is set, or enqueued on
``output_async_queue`` for fire-and-forget aborts.
"""
request_ids = msg.request_ids
error: str | None = None
abort_outputs: list[OutputMessage] = []
try:
# _cleanup_request_ids is CFG-aware: it expands aborted parents to
# their companions and fails a deferred parent whose companion is
# aborted before its output arrived.
await self._cleanup_request_ids(list(request_ids), abort=True)
abort_outputs = await self._cleanup_request_ids(list(request_ids), abort=True)
logger.info("[Orchestrator] Aborted request(s) %s", request_ids)
except Exception as exc:
error = str(exc)
@@ -893,8 +898,12 @@ class Orchestrator:
rpc_id=msg.rpc_id,
success=error is None,
error=error,
abort_outputs=abort_outputs or None,
)
)
elif abort_outputs:
for output_msg in abort_outputs:
await self.output_async_queue.put(output_msg)
async def _handle_interaction(self, msg: InteractionMessage) -> None:
"""Handle a midway interaction for an active streaming diffusion request."""
@@ -934,13 +943,53 @@ class Orchestrator:
)
)
async def _abort_request_ids(self, request_ids: list[str]) -> None:
"""Forward abort requests to all stage pools."""
async def _abort_request_ids(self, request_ids: list[str]) -> list[OutputMessage]:
"""Forward abort requests to all stage pools.
Collects final-stage AR abort outputs (partial tokens) while request
state is still available for stage-id filtering. Diffusion pools do
not contribute abort outputs.
"""
if not request_ids:
return
return []
abort_outputs: list[OutputMessage] = []
for pool in self.stage_pools:
await pool.abort_requests(request_ids)
stage_outputs = await pool.abort_requests(request_ids) or []
if bool(getattr(pool, "final_output", False)) and getattr(pool, "stage_type", None) != "diffusion":
final_output_type = getattr(pool.stage_client, "final_output_type", None) or "text"
for orch_req_id, request_output in stage_outputs:
req_state = self.request_states.get(orch_req_id)
if req_state is None:
continue
final_stage_ids = req_state.final_output_stage_ids or {req_state.final_stage_id}
if pool.stage_id not in final_stage_ids:
continue
engine_output = OmniRequestOutput.from_stage_output(
request_output,
request_id=orch_req_id,
finished=True,
stage_id=pool.stage_id,
replica_id=pool.get_bound_replica_id(orch_req_id),
final_output_type=final_output_type,
)
abort_outputs.append(
OutputMessage(
request_id=orch_req_id,
stage_id=pool.stage_id,
replica_id=pool.get_bound_replica_id(orch_req_id),
engine_outputs=engine_output,
metrics=None,
finished=False,
stage_submit_ts=req_state.stage_submit_ts.get(pool.stage_id),
)
)
pool.release_bindings(request_ids)
last_index_by_req: dict[str, int] = {}
for index, output_msg in enumerate(abort_outputs):
last_index_by_req[output_msg.request_id] = index
for index, output_msg in enumerate(abort_outputs):
output_msg.finished = index == last_index_by_req[output_msg.request_id]
return abort_outputs
def _release_request_bindings(self, request_ids: list[str]) -> None:
"""Release all stage-local route bindings for the given request ids."""
@@ -1688,7 +1737,7 @@ class Orchestrator:
*,
abort: bool = False,
close_duplex_sessions: bool = False,
) -> None:
) -> list[OutputMessage]:
"""Release pool bindings and logical request state for the given ids.
CFG-aware: cleaning a parent releases its tracker state and pulls its
@@ -1697,9 +1746,13 @@ class Orchestrator:
can never complete). Every teardown path (stage error, abort, replica
loss, membership unregister) funnels through here, so tracker state
cannot outlive its requests.
Returns:
Final-stage AR abort ``OutputMessage`` list when ``abort=True``;
otherwise an empty list.
"""
if not request_ids:
return
return []
cleanup_ids = list(dict.fromkeys(request_ids))
batch = set(cleanup_ids)
@@ -1741,9 +1794,10 @@ class Orchestrator:
cleanup_ids.extend(stale_request_ids)
cleanup_ids = list(dict.fromkeys(cleanup_ids))
abort_outputs: list[OutputMessage] = []
try:
if abort:
await self._abort_request_ids(cleanup_ids)
abort_outputs = await self._abort_request_ids(cleanup_ids)
self._release_request_bindings(cleanup_ids)
for request_id in cleanup_ids:
self._pd_kv_params.pop(request_id, None)
@@ -1759,6 +1813,7 @@ class Orchestrator:
raise
if closing_session_ids and self.duplex_control_plane is not None:
self.duplex_control_plane.finalize_closed_sessions(closing_session_ids)
return abort_outputs
async def _apply_raw_terminal_stage_finish(
self,