refactor: 推进后端分层架构治理

This commit is contained in:
jxxghp
2026-08-18 00:29:14 +08:00
parent 5d0bacabd5
commit 5128ae9e1e
363 changed files with 34179 additions and 6019 deletions
+117 -3
View File
@@ -19,7 +19,7 @@ from app.adapters.system.host import SystemUtils
from app.runtime.log import logger
from app.runtime.config import settings
from app.runtime.extensions.module_manager import ModuleManager
from app.runtime.events import EventManager
from app.runtime.events import EventHandlerBinding, EventManager
from app.runtime.state import SystemHelper
from app.runtime.thread import ThreadHelper
from app.adapters.network.doh import DohHelper
@@ -28,11 +28,19 @@ from app.adapters.system.resource import (
configure_resource_version_provider,
)
from app.application.messaging.message import MessageHelper, stop_message
from app.adapters.external.server import MoviePilotServerHelper
from app.adapters.external.server import (
MoviePilotServerHelper,
configure_server_application_services,
)
from app.application.server.report import ServerReportService
from app.application.server.share import ServerSharingService
from app.db import close_database
from app.db.oper.subscribe import SubscribeOper
from app.db.oper.systemconfig import SystemConfigOper
from app.db.oper.workflow import WorkflowOper
from app.command import CommandChain
from app.schemas import Message, MessageType
from app.schemas.message import Message
from app.schemas.message import MessageType
from app.schemas.types import SystemConfigKey
from app.startup.agent_initializer import init_agent, stop_agent
from app.startup.managed_resources_initializer import (
@@ -42,6 +50,62 @@ from app.startup.managed_resources_initializer import (
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
from app.application.chain.context import (
build_default_chain_runtime_context,
configure_chain_runtime_context_provider,
)
from app.runtime.extensions.service_config import configure_service_config_reader
async def _async_get_subscribe(subscribe_id: int):
"""通过数据库操作器异步读取订阅,供服务端共享用例使用。"""
return await SubscribeOper().async_get(subscribe_id)
async def _async_get_workflow(workflow_id: int):
"""通过数据库操作器异步读取工作流,供服务端共享用例使用。"""
return await WorkflowOper().async_get(workflow_id)
def configure_runtime_data_providers() -> None:
"""在启动组合层装配运行时和外部服务所需的数据库读取能力。"""
configure_service_config_reader(lambda key: SystemConfigOper().get(key))
configure_server_application_services(
report_service=ServerReportService(
config_reader=lambda key: SystemConfigOper().get(key),
config_writer=lambda key, value: SystemConfigOper().set(key, value),
installed_plugins_provider=lambda: SystemConfigOper().get(
SystemConfigKey.UserInstalledPlugins
) or [],
subscribes_provider=lambda: SubscribeOper().list(),
plugin_report_sender=MoviePilotServerHelper.plugin_install_report,
async_plugin_report_sender=(
MoviePilotServerHelper.async_plugin_install_report
),
subscribe_report_sender=MoviePilotServerHelper.subscribe_report,
repo_url_sanitizer=MoviePilotServerHelper.sanitize_plugin_repo_url,
),
sharing_service=ServerSharingService(
subscribe_provider=lambda subscribe_id: SubscribeOper().get(
subscribe_id
),
async_subscribe_provider=_async_get_subscribe,
workflow_provider=lambda workflow_id: WorkflowOper().get(workflow_id),
async_workflow_provider=_async_get_workflow,
user_uuid_provider=MoviePilotServerHelper.get_user_uuid,
subscribe_sender=MoviePilotServerHelper.subscribe_share,
async_subscribe_sender=MoviePilotServerHelper.async_subscribe_share,
workflow_sender=MoviePilotServerHelper.workflow_share,
async_workflow_sender=MoviePilotServerHelper.async_workflow_share,
response_handler=MoviePilotServerHelper._handle_response,
subscribe_cache_clearer=(
MoviePilotServerHelper._clear_subscribe_share_cache
),
workflow_cache_clearer=(
MoviePilotServerHelper._clear_workflow_share_cache
),
),
)
def configure_wallpaper_services() -> None:
@@ -65,6 +129,50 @@ def notify_event_error(title: str, message: str) -> None:
)
def get_host_event_handler_factories() -> dict[type, Callable[[], object]]:
"""返回所有使用事件装饰器的宿主类及其明确实例工厂。"""
from app.chain.download import DownloadChain
from app.chain.scraping import ScrapingChain
from app.chain.search import SearchChain
from app.chain.site import SiteChain
from app.chain.subscribe import SubscribeChain
from app.chain.workflow import WorkflowChain
from app.command import Command
from app.scheduler import Scheduler
return {
Command: Command,
DownloadChain: DownloadChain,
Scheduler: Scheduler,
ScrapingChain: ScrapingChain,
SearchChain: SearchChain,
SiteChain: SiteChain,
SubscribeChain: SubscribeChain,
WorkflowChain: WorkflowChain,
}
def configure_host_event_handler_resolver() -> None:
"""显式登记宿主内置类处理器,禁止事件总线按类名临时构造未知对象。"""
factories = get_host_event_handler_factories()
def resolve(owner_class: type) -> EventHandlerBinding | None:
"""按明确白名单复用单例或构造与旧路径等价的 Chain 实例。"""
factory = factories.get(owner_class)
if factory is None:
return None
get_existing = getattr(owner_class, "get_existing_instance", None)
instance = get_existing() if callable(get_existing) else None
if instance is None:
instance = factory()
return EventHandlerBinding(
instance=instance,
owner_name=owner_class.__name__,
)
EventManager().register_handler_instance_resolver("host", resolve)
def start_frontend():
"""
启动前端服务
@@ -212,10 +320,14 @@ async def init_modules():
"""
启动模块
"""
# 数据访问能力统一在启动组合根注入,Runtime 和 Adapter 不再直接依赖 Oper。
configure_runtime_data_providers()
# 托管资源只在这里装配声明与 adapter,具体资源仍由首个消费者显式激活。
init_managed_resources()
# 应用服务不反向依赖 Chain,由启动组合层注入壁纸来源。
configure_wallpaper_services()
# Chain 无参兼容入口由组合根明确提供依赖上下文;测试和新代码可直接注入替代上下文。
configure_chain_runtime_context_provider(build_default_chain_runtime_context)
# 认证访问层不反向依赖数据库实现,由启动组合层注入载荷提供器。
set_superuser_token_payload_provider(build_superuser_token_payload)
# DoH
@@ -228,6 +340,8 @@ async def init_modules():
user_auth()
# 事件错误通知由启动组合层接入消息服务。
EventManager().set_error_notifier(notify_event_error)
# 宿主类处理器在启动层显式登记,事件总线不再兜底 owner_class()。
configure_host_event_handler_resolver()
# 加载模块
ModuleManager()
# 启动事件消费