refactor(runtime): activate managed resources on demand (#6334)

This commit is contained in:
InfinityPacer
2026-08-16 16:44:45 +08:00
committed by GitHub
parent 7e851dbfa7
commit b8b59ae20a
27 changed files with 3068 additions and 116 deletions
@@ -0,0 +1,47 @@
"""Managed Resource 的启动组合与进程关闭入口。"""
from __future__ import annotations
import threading
from typing import Optional
from app.runtime.capabilities.runtime import CapabilityRuntime
from app.runtime.extensions.managed_resource_adapter import (
AsyncManagedResourceAdapter,
SyncManagedResourceAdapter,
build_managed_resource_registry,
)
from app.runtime.managed_resources import (
MANAGED_RESOURCE_ASYNC_KIND,
MANAGED_RESOURCE_SYNC_KIND,
configure_managed_resource_runtime,
)
_runtime_lock = threading.RLock()
_managed_resource_runtime: Optional[CapabilityRuntime] = None
def init_managed_resources() -> CapabilityRuntime:
"""构建并注入资源 Runtime;只发现声明,不物化或启动任何资源。"""
global _managed_resource_runtime
with _runtime_lock:
if _managed_resource_runtime is None:
_managed_resource_runtime = CapabilityRuntime(
build_managed_resource_registry(),
adapters={
MANAGED_RESOURCE_SYNC_KIND: SyncManagedResourceAdapter(),
MANAGED_RESOURCE_ASYNC_KIND: AsyncManagedResourceAdapter(),
},
)
configure_managed_resource_runtime(_managed_resource_runtime)
return _managed_resource_runtime
async def stop_managed_resources() -> None:
"""关闭已经初始化的资源 Runtime;未初始化时不执行发现或激活。"""
with _runtime_lock:
runtime = _managed_resource_runtime
if runtime is None:
return
await runtime.shutdown_async(reason="application_shutdown")
+15 -4
View File
@@ -22,7 +22,6 @@ from app.runtime.extensions.module_manager import ModuleManager
from app.runtime.events import EventManager
from app.runtime.state import SystemHelper
from app.runtime.thread import ThreadHelper
from app.adapters.system.display import DisplayHelper
from app.adapters.network.doh import DohHelper
from app.adapters.system.resource import (
ResourceHelper,
@@ -36,6 +35,10 @@ from app.command import CommandChain
from app.schemas import Notification, NotificationType
from app.schemas.types import SystemConfigKey
from app.startup.agent_initializer import init_agent, stop_agent
from app.startup.managed_resources_initializer import (
init_managed_resources,
stop_managed_resources,
)
from app.application.security.access import set_superuser_token_payload_provider
from app.application.security.auth import build_superuser_token_payload
from app.application.image import configure_wallpaper_providers
@@ -170,6 +173,13 @@ def update_resources() -> None:
logger.error(f"资源更新完成但自动重启失败:{message}")
def close_browser_sessions() -> None:
"""在托管资源关闭前释放所有浏览器上下文及其工作线程。"""
from app.adapters.network.browser import BrowserSessionHelper
BrowserSessionHelper.close_all_sessions()
async def stop_modules():
"""
服务关闭
@@ -186,7 +196,8 @@ async def stop_modules():
await run_step("AI智能体", stop_agent)
await run_step("模块", lambda: ModuleManager().shutdown())
await run_step("事件消费", lambda: EventManager().stop())
await run_step("虚拟显示", lambda: DisplayHelper().stop())
await run_step("浏览器会话", close_browser_sessions)
await run_step("托管资源", stop_managed_resources)
await run_step("DoH服务", lambda: DohHelper().shutdown())
await run_step("线程池", lambda: ThreadHelper().shutdown())
await run_step("消息服务", stop_message)
@@ -201,12 +212,12 @@ async def init_modules():
"""
启动模块
"""
# 托管资源只在这里装配声明与 adapter,具体资源仍由首个消费者显式激活。
init_managed_resources()
# 应用服务不反向依赖 Chain,由启动组合层注入壁纸来源。
configure_wallpaper_services()
# 认证访问层不反向依赖数据库实现,由启动组合层注入载荷提供器。
set_superuser_token_payload_provider(build_superuser_token_payload)
# 虚拟显示
DisplayHelper()
# DoH
DohHelper()
# 站点管理
+15
View File
@@ -1,25 +1,40 @@
from pathlib import Path
from app.runtime.compat.diagnostics import (
configure_legacy_import_diagnostics,
scan_plugin_legacy_imports,
)
from app.runtime.compat.resource_imports import scan_plugin_resource_imports
from app.runtime.config import global_vars
from app.runtime.extensions.plugin_manager import (
PluginManager,
configure_plugin_install_reporter,
configure_plugin_legacy_import_services,
configure_plugin_resource_import_preparer,
configure_site_auth_level_provider,
)
from app.runtime.managed_resources import acquire_managed_resource
from app.application.site.sites import SitesHelper # pylint: disable=no-name-in-module
from app.adapters.external.server import MoviePilotServerHelper
from app.runtime.log import logger
def _prepare_legacy_plugin_import(*, plugin_id: str, plugin_dir: Path) -> None:
"""在执行旧插件顶层代码前准备其静态导入所需的宿主资源。"""
for capability_id in scan_plugin_resource_imports(plugin_id, plugin_dir):
acquire_managed_resource(
capability_id,
reason="legacy_plugin_import",
)
def _configure_plugin_services() -> None:
"""把兼容诊断、远程上报和站点认证等级装配到插件管理器。"""
configure_plugin_legacy_import_services(
diagnostics_configurator=configure_legacy_import_diagnostics,
import_scanner=scan_plugin_legacy_imports,
)
configure_plugin_resource_import_preparer(_prepare_legacy_plugin_import)
configure_plugin_install_reporter(MoviePilotServerHelper.install_plugin_reg)
configure_site_auth_level_provider(lambda: SitesHelper().auth_level)