[Bugfix][Engine] Make abort idempotent during shutdown (#6327)
Signed-off-by: Allen Wu <allenwu2795@gmail.com> Co-authored-by: TRAE CLI <noreply@bytedance.com> Co-authored-by: TRAE CLI <traecli@bytedance.com>
This commit is contained in:
5 files changed
+295
-8
No files matched your search
@@ -1,3 +1,6 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
|
||||
|
||||
import pytest
|
||||
import torch
|
||||
from pytest_mock import MockerFixture
|
||||
@@ -14,6 +17,104 @@ from vllm_omni.model_executor.stage_input_processors.bagel import ExpandedPrompt
|
||||
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
|
||||
|
||||
|
||||
class _SyntheticSyncQueueShutDownError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def test_abort_is_noop_for_empty_request_ids(mocker: MockerFixture):
|
||||
engine = object.__new__(AsyncOmniEngine)
|
||||
engine._shutdown_called = False
|
||||
engine.request_queue = mocker.Mock()
|
||||
|
||||
engine.abort([])
|
||||
|
||||
engine.request_queue.sync_q.put.assert_not_called()
|
||||
|
||||
|
||||
def test_abort_is_noop_after_shutdown_starts(mocker: MockerFixture):
|
||||
engine = object.__new__(AsyncOmniEngine)
|
||||
engine._shutdown_called = True
|
||||
engine.request_queue = mocker.Mock()
|
||||
|
||||
engine.abort(["req-1"])
|
||||
|
||||
engine.request_queue.sync_q.put.assert_not_called()
|
||||
|
||||
|
||||
def test_abort_tolerates_queue_close_race_during_shutdown(mocker: MockerFixture):
|
||||
engine = object.__new__(AsyncOmniEngine)
|
||||
engine._shutdown_called = False
|
||||
engine.request_queue = mocker.Mock()
|
||||
mocker.patch(
|
||||
"vllm_omni.engine.async_engine_utils._JANUS_SYNC_QUEUE_SHUTDOWN",
|
||||
_SyntheticSyncQueueShutDownError,
|
||||
)
|
||||
|
||||
def close_queue_during_abort(*args, **kwargs):
|
||||
del args, kwargs
|
||||
engine._shutdown_called = True
|
||||
raise _SyntheticSyncQueueShutDownError
|
||||
|
||||
engine.request_queue.sync_q.put.side_effect = close_queue_during_abort
|
||||
|
||||
engine.abort(["req-1"])
|
||||
|
||||
|
||||
def test_abort_tolerates_legacy_janus_close_error_during_shutdown(mocker: MockerFixture):
|
||||
engine = object.__new__(AsyncOmniEngine)
|
||||
engine._shutdown_called = False
|
||||
engine.request_queue = mocker.Mock()
|
||||
mocker.patch(
|
||||
"vllm_omni.engine.async_engine_utils._JANUS_SYNC_QUEUE_SHUTDOWN",
|
||||
None,
|
||||
)
|
||||
|
||||
def close_queue_during_abort(*args, **kwargs):
|
||||
del args, kwargs
|
||||
engine._shutdown_called = True
|
||||
raise RuntimeError("Operation on the closed queue is forbidden")
|
||||
|
||||
engine.request_queue.sync_q.put.side_effect = close_queue_during_abort
|
||||
|
||||
engine.abort(["req-1"])
|
||||
|
||||
|
||||
def test_abort_surfaces_unrelated_legacy_runtime_error_during_shutdown(
|
||||
mocker: MockerFixture,
|
||||
):
|
||||
engine = object.__new__(AsyncOmniEngine)
|
||||
engine._shutdown_called = False
|
||||
engine.request_queue = mocker.Mock()
|
||||
mocker.patch(
|
||||
"vllm_omni.engine.async_engine_utils._JANUS_SYNC_QUEUE_SHUTDOWN",
|
||||
None,
|
||||
)
|
||||
|
||||
def fail_during_abort(*args, **kwargs):
|
||||
del args, kwargs
|
||||
engine._shutdown_called = True
|
||||
raise RuntimeError("unrelated queue failure")
|
||||
|
||||
engine.request_queue.sync_q.put.side_effect = fail_during_abort
|
||||
|
||||
with pytest.raises(RuntimeError, match="unrelated queue failure"):
|
||||
engine.abort(["req-1"])
|
||||
|
||||
|
||||
def test_abort_surfaces_unexpected_closed_queue(mocker: MockerFixture):
|
||||
engine = object.__new__(AsyncOmniEngine)
|
||||
engine._shutdown_called = False
|
||||
engine.request_queue = mocker.Mock()
|
||||
mocker.patch(
|
||||
"vllm_omni.engine.async_engine_utils._JANUS_SYNC_QUEUE_SHUTDOWN",
|
||||
_SyntheticSyncQueueShutDownError,
|
||||
)
|
||||
engine.request_queue.sync_q.put.side_effect = _SyntheticSyncQueueShutDownError
|
||||
|
||||
with pytest.raises(_SyntheticSyncQueueShutDownError):
|
||||
engine.abort(["req-1"])
|
||||
|
||||
|
||||
def _make_engine_core_request(request_id: str = "req-1") -> EngineCoreRequest:
|
||||
return EngineCoreRequest(
|
||||
request_id=request_id,
|
||||
|
||||
Reference in new issue
Block a user