fix: 修复 Windows 平台下信号处理器注册问题,避免不必要的注册尝试
This commit is contained in:
@@ -534,6 +534,22 @@ class TestSDK:
|
||||
class TestPluginSdkUsage:
|
||||
"""验证仓库内插件按新 SDK 归一化返回值工作。"""
|
||||
|
||||
def test_runner_skips_signal_handler_registration_on_windows(self, monkeypatch):
|
||||
"""Windows 下不应尝试注册 add_signal_handler。"""
|
||||
from src.plugin_runtime.runner import runner_main
|
||||
|
||||
registered_signals = []
|
||||
|
||||
class DummyLoop:
|
||||
def add_signal_handler(self, sig, callback):
|
||||
registered_signals.append((sig, callback))
|
||||
|
||||
monkeypatch.setattr(runner_main.sys, "platform", "win32")
|
||||
|
||||
runner_main._install_shutdown_signal_handlers(lambda: None, DummyLoop())
|
||||
|
||||
assert not registered_signals
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_builtin_emoji_plugin_handles_normalized_results(self):
|
||||
from maibot_sdk.context import PluginContext
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
6. 转发插件的能力调用到 Host
|
||||
"""
|
||||
|
||||
from typing import Any, List, Optional, Protocol, cast
|
||||
from typing import Any, Callable, List, Optional, Protocol, cast
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
@@ -47,6 +47,29 @@ class _ContextAwarePlugin(Protocol):
|
||||
def _set_context(self, context: Any) -> None: ...
|
||||
|
||||
|
||||
def _install_shutdown_signal_handlers(
|
||||
mark_runner_shutting_down: Callable[[], None],
|
||||
loop: Optional[asyncio.AbstractEventLoop] = None,
|
||||
) -> None:
|
||||
"""为 Runner 注册关停信号处理器。
|
||||
|
||||
Windows 默认事件循环不支持 add_signal_handler,且当前 Runner 在 Windows
|
||||
下由 Host 直接 terminate/kill,不依赖进程内信号回调进行优雅收尾。
|
||||
"""
|
||||
if sys.platform == "win32":
|
||||
return
|
||||
|
||||
target_loop = loop or asyncio.get_running_loop()
|
||||
for sig in (signal.SIGTERM, signal.SIGINT):
|
||||
try:
|
||||
target_loop.add_signal_handler(sig, mark_runner_shutting_down)
|
||||
except Exception as exc:
|
||||
if not isinstance(exc, (NotImplementedError, RuntimeError)):
|
||||
raise
|
||||
logger.debug(f"当前事件循环不支持注册 Runner 信号处理器: {exc}")
|
||||
return
|
||||
|
||||
|
||||
def _disable_runner_console_logging() -> None:
|
||||
"""关闭 Runner 的控制台日志输出,避免被 Host 从 stderr 二次包装。"""
|
||||
root_logger = stdlib_logging.getLogger()
|
||||
@@ -666,14 +689,7 @@ async def _async_main() -> None:
|
||||
def _mark_runner_shutting_down() -> None:
|
||||
runner._shutting_down = True
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
for sig in (signal.SIGTERM, signal.SIGINT):
|
||||
try:
|
||||
loop.add_signal_handler(sig, _mark_runner_shutting_down)
|
||||
except NotImplementedError:
|
||||
logger.warning(f"当前平台/事件循环不支持 signal handler,跳过注册信号 {sig!s}")
|
||||
except RuntimeError as exc:
|
||||
logger.warning(f"注册信号处理器失败,跳过信号 {sig!s}: {exc}")
|
||||
_install_shutdown_signal_handlers(_mark_runner_shutting_down)
|
||||
|
||||
await runner.run()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user