mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-06 16:07:01 +08:00
refactor: inject DoH runtime settings
This commit is contained in:
@@ -5,6 +5,7 @@ author: https://github.com/C5H12O5/syno-videoinfo-plugin
|
|||||||
import base64
|
import base64
|
||||||
import concurrent
|
import concurrent
|
||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
|
import importlib
|
||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
@@ -13,7 +14,7 @@ import urllib.request
|
|||||||
from threading import Lock
|
from threading import Lock
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
from app.runtime.config import settings
|
from app.application.configuration import get_runtime_settings
|
||||||
from app.runtime.log import logger
|
from app.runtime.log import logger
|
||||||
from app.runtime.reload import ConfigReloadMixin
|
from app.runtime.reload import ConfigReloadMixin
|
||||||
from app.foundation.singleton import Singleton
|
from app.foundation.singleton import Singleton
|
||||||
@@ -31,6 +32,15 @@ _doh_lock = Lock()
|
|||||||
_orig_getaddrinfo = socket.getaddrinfo
|
_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)
|
||||||
|
|
||||||
|
|
||||||
def _get_executor_locked() -> concurrent.futures.ThreadPoolExecutor:
|
def _get_executor_locked() -> concurrent.futures.ThreadPoolExecutor:
|
||||||
"""在持有执行器锁时按需获取 DoH 查询线程池"""
|
"""在持有执行器锁时按需获取 DoH 查询线程池"""
|
||||||
global _executor
|
global _executor
|
||||||
@@ -50,7 +60,7 @@ def enable_doh(enable: bool) -> None:
|
|||||||
"""
|
"""
|
||||||
socket.getaddrinfo的补丁版本。
|
socket.getaddrinfo的补丁版本。
|
||||||
"""
|
"""
|
||||||
if host not in settings.DOH_DOMAINS.split(","):
|
if host not in _doh_setting("DOH_DOMAINS").split(","):
|
||||||
return _orig_getaddrinfo(host, *args, **kwargs)
|
return _orig_getaddrinfo(host, *args, **kwargs)
|
||||||
# 检查主机是否已解析
|
# 检查主机是否已解析
|
||||||
with _doh_lock:
|
with _doh_lock:
|
||||||
@@ -66,7 +76,7 @@ def enable_doh(enable: bool) -> None:
|
|||||||
# 一次解析的任务必须在同一临界区提交完,避免关闭过程中部分任务落入新线程池
|
# 一次解析的任务必须在同一临界区提交完,避免关闭过程中部分任务落入新线程池
|
||||||
futures = [
|
futures = [
|
||||||
executor.submit(_doh_query, resolver, host)
|
executor.submit(_doh_query, resolver, host)
|
||||||
for resolver in settings.DOH_RESOLVERS.split(",")
|
for resolver in _doh_setting("DOH_RESOLVERS").split(",")
|
||||||
]
|
]
|
||||||
for future in concurrent.futures.as_completed(futures):
|
for future in concurrent.futures.as_completed(futures):
|
||||||
ip = future.result()
|
ip = future.result()
|
||||||
@@ -91,11 +101,11 @@ class DohHelper(ConfigReloadMixin, metaclass=Singleton):
|
|||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""按当前配置安装或移除 DoH 解析器。"""
|
"""按当前配置安装或移除 DoH 解析器。"""
|
||||||
enable_doh(settings.DOH_ENABLE)
|
enable_doh(_doh_setting("DOH_ENABLE"))
|
||||||
|
|
||||||
def on_config_changed(self) -> None:
|
def on_config_changed(self) -> None:
|
||||||
"""配置变化时清理缓存并重新应用 DoH 状态。"""
|
"""配置变化时清理缓存并重新应用 DoH 状态。"""
|
||||||
if not settings.DOH_ENABLE:
|
if not _doh_setting("DOH_ENABLE"):
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
return
|
return
|
||||||
with _doh_lock:
|
with _doh_lock:
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ MoviePilot V3 当前不是“目录混乱、必须推倒重来”的状态。第
|
|||||||
| legacy 默认模块契约 | 0 个宿主观察方法;未知动态方法保留 fallback | 所有静态宿主方法已有显式 V2 spec;真实 fallback 命中由 `module.contract.legacy_hit` 观测 |
|
| legacy 默认模块契约 | 0 个宿主观察方法;未知动态方法保留 fallback | 所有静态宿主方法已有显式 V2 spec;真实 fallback 命中由 `module.contract.legacy_hit` 观测 |
|
||||||
| 事件枚举 | 53 | 66 个静态 producer、15 个静态 consumer |
|
| 事件枚举 | 53 | 66 个静态 producer、15 个静态 consumer |
|
||||||
| 专用 EventData model | 53 | Event Contract Registry 已为全部事件登记 typed payload/fallback 原因 |
|
| 专用 EventData model | 53 | Event Contract Registry 已为全部事件登记 typed payload/fallback 原因 |
|
||||||
| 直接读取 `settings` 的文件 | 119 | 仍按模块族迁移,动态协议和安全端口暂保留 |
|
| 直接读取 `settings` 的文件 | 118 | 仍按模块族迁移,动态协议和安全端口暂保留 |
|
||||||
| `SystemConfigOper()` | 1 个 | 仅组合根创建 `SystemConfigService` 时保留 |
|
| `SystemConfigOper()` | 1 个 | 仅组合根创建 `SystemConfigService` 时保留 |
|
||||||
| Model 上的 DB 查询装饰器 | 119 | `db_update`/`async_db_update` 为 0;查询 ABI 继续按 canonical 用例迁移 |
|
| Model 上的 DB 查询装饰器 | 119 | `db_update`/`async_db_update` 为 0;查询 ABI 继续按 canonical 用例迁移 |
|
||||||
| 路由端点 | 335 | 11 个已装饰端点超过 80 行,最大 400 行 |
|
| 路由端点 | 335 | 11 个已装饰端点超过 80 行,最大 400 行 |
|
||||||
@@ -1021,6 +1021,7 @@ MFA/Passkey 专项测试与架构门禁通过,密钥类配置仍保留在安
|
|||||||
2026-08-23 将 `AgentRuntimeManager` 的默认 Agent 目录改为通过 `RuntimeSettingsService` 读取配置快照;显式目录参数和导入早期的旧设置回退保持不变。配置债务由 122 个文件降至 121 个文件,并补充默认目录注入回归测试。
|
2026-08-23 将 `AgentRuntimeManager` 的默认 Agent 目录改为通过 `RuntimeSettingsService` 读取配置快照;显式目录参数和导入早期的旧设置回退保持不变。配置债务由 122 个文件降至 121 个文件,并补充默认目录注入回归测试。
|
||||||
2026-08-23 将 `OcrHelper` 的服务地址改为通过 `RuntimeSettingsService` 或显式构造参数取得;导入早期保留旧模块回退,自动补齐 `/captcha/base64` 路径。配置债务由 121 个文件降至 120 个文件,并补充 OCR 地址注入回归测试。
|
2026-08-23 将 `OcrHelper` 的服务地址改为通过 `RuntimeSettingsService` 或显式构造参数取得;导入早期保留旧模块回退,自动补齐 `/captcha/base64` 路径。配置债务由 121 个文件降至 120 个文件,并补充 OCR 地址注入回归测试。
|
||||||
2026-08-23 将 `CookieCloudHelper` 的五项运行配置改为通过 `RuntimeSettingsService` 读取;同步期间仍获取最新值,未装配时保留旧 Settings ABI。配置债务由 120 个文件降至 119 个文件,并通过 CookieCloud 路由与站点回归测试。
|
2026-08-23 将 `CookieCloudHelper` 的五项运行配置改为通过 `RuntimeSettingsService` 读取;同步期间仍获取最新值,未装配时保留旧 Settings ABI。配置债务由 120 个文件降至 119 个文件,并通过 CookieCloud 路由与站点回归测试。
|
||||||
|
2026-08-23 将 DoH 开关、域名和解析器配置改为通过 `RuntimeSettingsService` 动态读取;socket 补丁、热更新、缓存和线程池关闭语义保持不变,未装配时保留旧 Settings ABI。配置债务由 119 个文件降至 118 个文件,并通过 DoH 与生命周期回归测试。
|
||||||
|
|
||||||
**收口记录(2026-08-22)**:`reidentify_cache`、`nettest`、`scrape`、OpenAI `chat_completions/responses`、`get_logging` 和 Web Agent SSE 均改为稳定公开入口委托私有编排实现;四个消息交互 Handler 的公开方法也保留 ABI 并委托私有状态机。复杂度基线已清零,API/Application/Chain 入口预算、异步阻塞 ratchet 均通过;复杂度及兼容专项合计 252 项测试通过。
|
**收口记录(2026-08-22)**:`reidentify_cache`、`nettest`、`scrape`、OpenAI `chat_completions/responses`、`get_logging` 和 Web Agent SSE 均改为稳定公开入口委托私有编排实现;四个消息交互 Handler 的公开方法也保留 ABI 并委托私有状态机。复杂度基线已清零,API/Application/Chain 入口预算、异步阻塞 ratchet 均通过;复杂度及兼容专项合计 252 项测试通过。
|
||||||
随后将 `TransferChain.do_transfer` 的公开入口收口为稳定兼容 Facade,先提取媒体身份规范化阶段,保留显式
|
随后将 `TransferChain.do_transfer` 的公开入口收口为稳定兼容 Facade,先提取媒体身份规范化阶段,保留显式
|
||||||
|
|||||||
@@ -9,14 +9,13 @@
|
|||||||
"root": "app"
|
"root": "app"
|
||||||
},
|
},
|
||||||
"settings_imports": {
|
"settings_imports": {
|
||||||
"count": 119,
|
"count": 118,
|
||||||
"files": [
|
"files": [
|
||||||
"app/adapters/cache/backends.py",
|
"app/adapters/cache/backends.py",
|
||||||
"app/adapters/cache/redis.py",
|
"app/adapters/cache/redis.py",
|
||||||
"app/adapters/external/market.py",
|
"app/adapters/external/market.py",
|
||||||
"app/adapters/external/server.py",
|
"app/adapters/external/server.py",
|
||||||
"app/adapters/network/browser.py",
|
"app/adapters/network/browser.py",
|
||||||
"app/adapters/network/doh.py",
|
|
||||||
"app/adapters/system/fsproxy.py",
|
"app/adapters/system/fsproxy.py",
|
||||||
"app/adapters/system/plugin/dependency.py",
|
"app/adapters/system/plugin/dependency.py",
|
||||||
"app/adapters/system/plugin/package.py",
|
"app/adapters/system/plugin/package.py",
|
||||||
|
|||||||
+4
-3
@@ -13,8 +13,8 @@
|
|||||||
"runtime_to_db": [],
|
"runtime_to_db": [],
|
||||||
"workflow_to_db": []
|
"workflow_to_db": []
|
||||||
},
|
},
|
||||||
"edge_count": 6418,
|
"edge_count": 6419,
|
||||||
"edge_sha256": "5849976e41ca96688d718358b3c1218d66d986efa0196051531be2a17aae1466",
|
"edge_sha256": "7e3db5ef8bc9be8d21706ad7a5f4b256430ea876afef66ca9ecf33ea2ff3c64e",
|
||||||
"edges": [
|
"edges": [
|
||||||
"app -> app.runtime",
|
"app -> app.runtime",
|
||||||
"app -> app.runtime.compat",
|
"app -> app.runtime.compat",
|
||||||
@@ -101,10 +101,11 @@
|
|||||||
"app.adapters.network.browser -> app.runtime.managed_resources",
|
"app.adapters.network.browser -> app.runtime.managed_resources",
|
||||||
"app.adapters.network.cloudflare -> app.runtime",
|
"app.adapters.network.cloudflare -> app.runtime",
|
||||||
"app.adapters.network.cloudflare -> app.runtime.log",
|
"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",
|
||||||
"app.adapters.network.doh -> app.foundation.singleton",
|
"app.adapters.network.doh -> app.foundation.singleton",
|
||||||
"app.adapters.network.doh -> app.runtime",
|
"app.adapters.network.doh -> app.runtime",
|
||||||
"app.adapters.network.doh -> app.runtime.config",
|
|
||||||
"app.adapters.network.doh -> app.runtime.log",
|
"app.adapters.network.doh -> app.runtime.log",
|
||||||
"app.adapters.network.doh -> app.runtime.reload",
|
"app.adapters.network.doh -> app.runtime.reload",
|
||||||
"app.adapters.network.http -> app.runtime",
|
"app.adapters.network.http -> app.runtime",
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ def test_doh_executor_is_lazy_and_shutdown_restores_socket(monkeypatch):
|
|||||||
"""DoH 线程池按需创建,并在模块关闭时恢复系统 DNS"""
|
"""DoH 线程池按需创建,并在模块关闭时恢复系统 DNS"""
|
||||||
original_getaddrinfo = socket.getaddrinfo
|
original_getaddrinfo = socket.getaddrinfo
|
||||||
helper = object.__new__(doh.DohHelper)
|
helper = object.__new__(doh.DohHelper)
|
||||||
monkeypatch.setattr(doh.settings, "DOH_DOMAINS", "example.com")
|
monkeypatch.setattr("app.runtime.config.settings.DOH_DOMAINS", "example.com")
|
||||||
monkeypatch.setattr(doh.settings, "DOH_RESOLVERS", "resolver.test")
|
monkeypatch.setattr("app.runtime.config.settings.DOH_RESOLVERS", "resolver.test")
|
||||||
monkeypatch.setattr(doh, "_doh_query", lambda resolver, host: "203.0.113.7")
|
monkeypatch.setattr(doh, "_doh_query", lambda resolver, host: "203.0.113.7")
|
||||||
monkeypatch.setattr(doh, "_orig_getaddrinfo", lambda host, *args, **kwargs: [])
|
monkeypatch.setattr(doh, "_orig_getaddrinfo", lambda host, *args, **kwargs: [])
|
||||||
|
|
||||||
@@ -35,8 +35,8 @@ def test_doh_config_reload_disables_and_closes_executor(monkeypatch):
|
|||||||
"""热更新关闭 DoH 时恢复系统 DNS 并释放已创建的线程池"""
|
"""热更新关闭 DoH 时恢复系统 DNS 并释放已创建的线程池"""
|
||||||
original_getaddrinfo = socket.getaddrinfo
|
original_getaddrinfo = socket.getaddrinfo
|
||||||
helper = object.__new__(doh.DohHelper)
|
helper = object.__new__(doh.DohHelper)
|
||||||
monkeypatch.setattr(doh.settings, "DOH_DOMAINS", "example.com")
|
monkeypatch.setattr("app.runtime.config.settings.DOH_DOMAINS", "example.com")
|
||||||
monkeypatch.setattr(doh.settings, "DOH_RESOLVERS", "resolver.test")
|
monkeypatch.setattr("app.runtime.config.settings.DOH_RESOLVERS", "resolver.test")
|
||||||
monkeypatch.setattr(doh, "_doh_query", lambda resolver, host: "203.0.113.7")
|
monkeypatch.setattr(doh, "_doh_query", lambda resolver, host: "203.0.113.7")
|
||||||
monkeypatch.setattr(doh, "_orig_getaddrinfo", lambda host, *args, **kwargs: [])
|
monkeypatch.setattr(doh, "_orig_getaddrinfo", lambda host, *args, **kwargs: [])
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ def test_doh_config_reload_disables_and_closes_executor(monkeypatch):
|
|||||||
socket.getaddrinfo("example.com", None)
|
socket.getaddrinfo("example.com", None)
|
||||||
executor = doh._executor
|
executor = doh._executor
|
||||||
assert executor is not None
|
assert executor is not None
|
||||||
monkeypatch.setattr(doh.settings, "DOH_ENABLE", False)
|
monkeypatch.setattr("app.runtime.config.settings.DOH_ENABLE", False)
|
||||||
|
|
||||||
helper.on_config_changed()
|
helper.on_config_changed()
|
||||||
|
|
||||||
@@ -73,8 +73,8 @@ def test_enable_doh_reuses_cached_host_resolution(monkeypatch):
|
|||||||
resolved_hosts.append(host)
|
resolved_hosts.append(host)
|
||||||
return [(socket.AF_INET, socket.SOCK_STREAM, 0, "", (host, 0))]
|
return [(socket.AF_INET, socket.SOCK_STREAM, 0, "", (host, 0))]
|
||||||
|
|
||||||
monkeypatch.setattr(doh.settings, "DOH_DOMAINS", "example.com")
|
monkeypatch.setattr("app.runtime.config.settings.DOH_DOMAINS", "example.com")
|
||||||
monkeypatch.setattr(doh.settings, "DOH_RESOLVERS", "resolver.test")
|
monkeypatch.setattr("app.runtime.config.settings.DOH_RESOLVERS", "resolver.test")
|
||||||
monkeypatch.setattr(doh, "_doh_query", fake_query)
|
monkeypatch.setattr(doh, "_doh_query", fake_query)
|
||||||
monkeypatch.setattr(doh, "_orig_getaddrinfo", fake_getaddrinfo)
|
monkeypatch.setattr(doh, "_orig_getaddrinfo", fake_getaddrinfo)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user