diff --git a/app/adapters/external/cookiecloud.py b/app/adapters/external/cookiecloud.py index 9f9f70165..573da8c4f 100644 --- a/app/adapters/external/cookiecloud.py +++ b/app/adapters/external/cookiecloud.py @@ -1,9 +1,8 @@ import json -import importlib from typing import Any, Dict, Tuple, Optional -from app.application.configuration import get_runtime_settings from app.runtime.log import logger +from app.runtime.settings import get_runtime_setting from app.foundation.crypto import CryptoJsUtils, HashUtils from app.adapters.network.http import RequestUtils from app.domain import site as site_rules @@ -13,11 +12,7 @@ from app.foundation.url import UrlUtils def _runtime_setting(key: str) -> Any: """读取 CookieCloud 配置服务,未装配时回退旧 Settings ABI。""" - try: - return get_runtime_settings().get(key) - except RuntimeError: - legacy_settings = importlib.import_module("app.runtime.config").settings - return getattr(legacy_settings, key) + return get_runtime_setting(key) class CookieCloudHelper: diff --git a/app/adapters/external/ocr.py b/app/adapters/external/ocr.py index f8935d164..7c639ee1e 100644 --- a/app/adapters/external/ocr.py +++ b/app/adapters/external/ocr.py @@ -1,9 +1,8 @@ import base64 -import importlib from typing import Optional -from app.application.configuration import get_runtime_settings from app.adapters.network.http import RequestUtils +from app.runtime.settings import get_runtime_setting class OcrHelper: @@ -14,11 +13,7 @@ class OcrHelper: def __init__(self, ocr_base_url: Optional[str] = None) -> None: """初始化 OCR 服务地址,优先使用组合根设置快照。""" if ocr_base_url is None: - try: - ocr_base_url = get_runtime_settings().get("OCR_HOST") - except RuntimeError: - legacy_settings = importlib.import_module("app.runtime.config").settings - ocr_base_url = legacy_settings.OCR_HOST + ocr_base_url = get_runtime_setting("OCR_HOST") self._ocr_b64_url = f"{str(ocr_base_url).rstrip('/')}/captcha/base64" def get_captcha_text( diff --git a/app/adapters/network/doh.py b/app/adapters/network/doh.py index e6859befa..a18eb2291 100644 --- a/app/adapters/network/doh.py +++ b/app/adapters/network/doh.py @@ -5,7 +5,6 @@ author: https://github.com/C5H12O5/syno-videoinfo-plugin import base64 import concurrent import concurrent.futures -import importlib import json import socket import struct @@ -14,9 +13,9 @@ import urllib.request from threading import Lock from typing import Dict, Optional -from app.application.configuration import get_runtime_settings from app.runtime.log import logger from app.runtime.reload import ConfigReloadMixin +from app.runtime.settings import get_runtime_setting from app.foundation.singleton import Singleton # DoH 关闭时需要释放线程池;保持惰性创建可避免未启用 DoH 时占用进程级资源 @@ -34,11 +33,7 @@ _orig_getaddrinfo = socket.getaddrinfo def _doh_setting(key: str): """读取 DoH 热更新配置,组合根未装配时兼容旧 Settings。""" - try: - return get_runtime_settings().get(key) - except RuntimeError: - legacy_settings = importlib.import_module("app.runtime.config").settings - return getattr(legacy_settings, key) + return get_runtime_setting(key) def _get_executor_locked() -> concurrent.futures.ThreadPoolExecutor: diff --git a/app/adapters/system/rust.py b/app/adapters/system/rust.py index 145b06d9b..cdb8a17f3 100644 --- a/app/adapters/system/rust.py +++ b/app/adapters/system/rust.py @@ -1,10 +1,9 @@ -import importlib import logging from functools import lru_cache from typing import List, Optional, Tuple -from app.application.configuration import get_runtime_settings from app.runtime.log import logger, log_settings +from app.runtime.settings import get_runtime_setting try: import moviepilot_rust as _moviepilot_rust @@ -17,11 +16,7 @@ else: def _rust_accel_enabled() -> bool: """读取 Rust 开关快照,组合根未装配时回退旧 Settings。""" - try: - return bool(get_runtime_settings().get("RUST_ACCEL")) - except RuntimeError: - legacy_settings = importlib.import_module("app.runtime.config").settings - return bool(legacy_settings.RUST_ACCEL) + return bool(get_runtime_setting("RUST_ACCEL")) def is_available() -> bool: diff --git a/app/runtime/settings.py b/app/runtime/settings.py new file mode 100644 index 000000000..9d57e9101 --- /dev/null +++ b/app/runtime/settings.py @@ -0,0 +1,25 @@ +"""运行时配置读取端口,供低层适配器避免反向依赖 Application。""" + +from __future__ import annotations + +import importlib +from collections.abc import Callable +from typing import Any + + +RuntimeSettingProvider = Callable[[str], Any] +_provider: RuntimeSettingProvider | None = None + + +def configure_runtime_setting_provider(provider: RuntimeSettingProvider) -> None: + """由启动组合根登记配置读取器,保持适配器只依赖 runtime 端口。""" + global _provider + _provider = provider + + +def get_runtime_setting(key: str) -> Any: + """读取单项运行配置;启动早期未装配时回退旧 Settings ABI。""" + if _provider is not None: + return _provider(key) + legacy_settings = importlib.import_module("app.runtime.config").settings + return getattr(legacy_settings, key) diff --git a/app/startup/modules_initializer.py b/app/startup/modules_initializer.py index 835908825..52260d4d7 100644 --- a/app/startup/modules_initializer.py +++ b/app/startup/modules_initializer.py @@ -25,6 +25,7 @@ from app.runtime.extensions.plugin_manager import PluginManager from app.runtime.events import EventHandlerBinding, EventManager from app.runtime.observability import record_metric from app.runtime.state import SystemHelper +from app.runtime.settings import configure_runtime_setting_provider from app.runtime.thread import ThreadHelper from app.adapters.network.doh import DohHelper from app.adapters.system.resource import ( @@ -596,6 +597,7 @@ async def init_modules() -> HostRuntime: ) configure_runtime_configuration(host_runtime.configuration) configure_runtime_settings(host_runtime.settings) + configure_runtime_setting_provider(lambda key: getattr(settings, key)) configure_token_runtime_config(lambda: build_token_runtime_config(settings)) # 先发布系统配置服务,后续启动组合步骤统一复用同一配置端口。 configure_system_config(SystemConfigService(repository=SystemConfigOper())) diff --git a/tests/conftest.py b/tests/conftest.py index 0ab210300..8584ed70c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -41,6 +41,7 @@ def configure_plugin_system_services(): configure_transfer_retry_config, ) from app.runtime.config import settings + from app.runtime.settings import configure_runtime_setting_provider from app.startup.configuration import ( build_api_runtime_config, build_chain_runtime_config, @@ -70,6 +71,7 @@ def configure_plugin_system_services(): ) ) configure_runtime_settings(RuntimeSettingsService(settings)) + configure_runtime_setting_provider(lambda key: getattr(settings, key)) configure_token_runtime_config(lambda: build_token_runtime_config(settings)) configure_system_config(SystemConfigService(repository=SystemConfigOper())) configure_transfer_retry_config( diff --git a/tests/fixtures/architecture/dependency-baseline.json b/tests/fixtures/architecture/dependency-baseline.json index 697753b33..902646e10 100644 --- a/tests/fixtures/architecture/dependency-baseline.json +++ b/tests/fixtures/architecture/dependency-baseline.json @@ -13,8 +13,8 @@ "runtime_to_db": [], "workflow_to_db": [] }, - "edge_count": 6420, - "edge_sha256": "c1d92730a7755f0b5da8d8f9b8ecc4b828f76b8eb90b6967d8f5a8bc600b0727", + "edge_count": 6418, + "edge_sha256": "8ec406999c67a103722fdb3e2cb641dff8addc83b4c60df7b0ea18027afdfb08", "edges": [ "app -> app.runtime", "app -> app.runtime.compat", @@ -34,8 +34,6 @@ "app.adapters.external.cookiecloud -> app.adapters", "app.adapters.external.cookiecloud -> app.adapters.network", "app.adapters.external.cookiecloud -> app.adapters.network.http", - "app.adapters.external.cookiecloud -> app.application", - "app.adapters.external.cookiecloud -> app.application.configuration", "app.adapters.external.cookiecloud -> app.domain", "app.adapters.external.cookiecloud -> app.domain.site", "app.adapters.external.cookiecloud -> app.foundation", @@ -44,6 +42,7 @@ "app.adapters.external.cookiecloud -> app.foundation.url", "app.adapters.external.cookiecloud -> app.runtime", "app.adapters.external.cookiecloud -> app.runtime.log", + "app.adapters.external.cookiecloud -> app.runtime.settings", "app.adapters.external.location -> app.adapters", "app.adapters.external.location -> app.adapters.network", "app.adapters.external.location -> app.adapters.network.http", @@ -67,8 +66,8 @@ "app.adapters.external.ocr -> app.adapters", "app.adapters.external.ocr -> app.adapters.network", "app.adapters.external.ocr -> app.adapters.network.http", - "app.adapters.external.ocr -> app.application", - "app.adapters.external.ocr -> app.application.configuration", + "app.adapters.external.ocr -> app.runtime", + "app.adapters.external.ocr -> app.runtime.settings", "app.adapters.external.plugin.client -> app.adapters", "app.adapters.external.plugin.client -> app.adapters.external", "app.adapters.external.plugin.client -> app.adapters.external.market", @@ -101,13 +100,12 @@ "app.adapters.network.browser -> app.runtime.managed_resources", "app.adapters.network.cloudflare -> app.runtime", "app.adapters.network.cloudflare -> app.runtime.log", - "app.adapters.network.doh -> app.application", - "app.adapters.network.doh -> app.application.configuration", "app.adapters.network.doh -> app.foundation", "app.adapters.network.doh -> app.foundation.singleton", "app.adapters.network.doh -> app.runtime", "app.adapters.network.doh -> app.runtime.log", "app.adapters.network.doh -> app.runtime.reload", + "app.adapters.network.doh -> app.runtime.settings", "app.adapters.network.http -> app.runtime", "app.adapters.network.http -> app.runtime.correlation", "app.adapters.observability.otel -> app.runtime", @@ -156,10 +154,9 @@ "app.adapters.system.resource -> app.runtime", "app.adapters.system.resource -> app.runtime.config", "app.adapters.system.resource -> app.runtime.log", - "app.adapters.system.rust -> app.application", - "app.adapters.system.rust -> app.application.configuration", "app.adapters.system.rust -> app.runtime", "app.adapters.system.rust -> app.runtime.log", + "app.adapters.system.rust -> app.runtime.settings", "app.adapters.web.correlation -> app.runtime", "app.adapters.web.correlation -> app.runtime.correlation", "app.adapters.web.health -> app.runtime", @@ -6149,6 +6146,7 @@ "app.startup.modules_initializer -> app.runtime.extensions.service_config", "app.startup.modules_initializer -> app.runtime.log", "app.startup.modules_initializer -> app.runtime.observability", + "app.startup.modules_initializer -> app.runtime.settings", "app.startup.modules_initializer -> app.runtime.state", "app.startup.modules_initializer -> app.runtime.thread", "app.startup.modules_initializer -> app.scheduler", @@ -6437,7 +6435,7 @@ "app.workflow.actions.transfer_file -> app.workflow", "app.workflow.actions.transfer_file -> app.workflow.actions" ], - "module_count": 795, + "module_count": 796, "modules": [ "app", "app.adapters", @@ -7126,6 +7124,7 @@ "app.runtime.rate", "app.runtime.reload", "app.runtime.scheduling", + "app.runtime.settings", "app.runtime.state", "app.runtime.thread", "app.runtime.topology",