refactor(database): isolate configuration transactions

This commit is contained in:
InfinityPacer
2026-08-23 02:29:22 +08:00
parent e99289a07b
commit 3d7fb44dc7
23 changed files with 1071 additions and 153 deletions
+9 -13
View File
@@ -4,9 +4,11 @@ from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from functools import partial
from pathlib import Path
from typing import Any, Optional, Protocol
from app.application.database import AsyncDatabaseExecutor
from app.schemas.types import MediaType
@@ -16,9 +18,6 @@ class SystemConfigReader(Protocol):
def get(self, key: Any = None) -> Any:
"""读取配置。"""
async def async_get(self, key: Any = None) -> Any:
"""异步读取配置。"""
class SystemConfigWriter(Protocol):
"""持久化用户配置的最小写入端口。"""
@@ -26,9 +25,6 @@ class SystemConfigWriter(Protocol):
def set(self, key: Any, value: Any) -> bool | None:
"""写入配置。"""
async def async_set(self, key: Any, value: Any) -> bool | None:
"""异步写入配置。"""
def delete(self, key: Any) -> Any:
"""删除配置。"""
@@ -296,14 +292,16 @@ class SystemConfigService:
*,
reader: SystemConfigReader | None = None,
writer: SystemConfigWriter | None = None,
async_executor: AsyncDatabaseExecutor | None = None,
) -> None:
"""注入可分离的读写端口,并兼容旧的单仓储装配参数"""
"""注入读写端口及可选的异步事务执行能力"""
resolved_reader = reader or repository
resolved_writer = writer or repository
if resolved_reader is None or resolved_writer is None:
raise ValueError("系统配置服务必须同时提供 reader 与 writer")
self._reader = resolved_reader
self._writer = resolved_writer
self._async_executor = async_executor
def get(self, key: Any = None) -> Any:
"""读取配置。"""
@@ -313,13 +311,11 @@ class SystemConfigService:
"""写入配置。"""
return self._writer.set(key, value)
async def async_get(self, key: Any = None) -> Any:
"""异步读取配置。"""
return await self._reader.async_get(key)
async def async_set(self, key: Any, value: Any) -> bool | None:
"""异步写入配置。"""
return await self._writer.async_set(key, value)
"""异步写入配置,并等待数据库提交或回滚完成"""
if self._async_executor is None:
raise RuntimeError("系统配置异步数据库执行端口尚未配置")
return await self._async_executor.run(partial(self._writer.set, key, value))
def delete(self, key: Any) -> Any:
"""删除配置。"""
+17 -7
View File
@@ -3,17 +3,27 @@
from __future__ import annotations
from collections.abc import Callable
from typing import Any, Optional
from typing import TYPE_CHECKING, Any, Optional, Protocol, TypeVar
from app.application.backup import (
BackupArtifact,
BackupVerification,
DatabaseBackupService,
)
from app.application.maintenance import DataCleanupService
if TYPE_CHECKING:
from app.application.backup import (
BackupArtifact,
BackupVerification,
DatabaseBackupService,
)
from app.application.maintenance import DataCleanupService
DatabaseProbe = Callable[[], Optional[str]]
T = TypeVar("T")
class AsyncDatabaseExecutor(Protocol):
"""让异步业务调用同步短事务而不阻塞事件循环。"""
async def run(self, operation: Callable[[], T]) -> T:
"""等待数据库操作完成提交或回滚,并返回执行结果。"""
...
class DatabaseHealthService:
+19 -2
View File
@@ -2,8 +2,11 @@
from __future__ import annotations
from functools import partial
from typing import Any, Protocol
from app.application.database import AsyncDatabaseExecutor
class UserConfigurationRepository(Protocol):
"""用户配置数据端口。"""
@@ -18,9 +21,15 @@ class UserConfigurationRepository(Protocol):
class UserConfigurationService:
"""编排用户个性化配置读写。"""
def __init__(self, repository: UserConfigurationRepository) -> None:
"""注入用户配置数据端口。"""
def __init__(
self,
repository: UserConfigurationRepository,
*,
async_executor: AsyncDatabaseExecutor | None = None,
) -> None:
"""注入用户配置数据端口及可选的异步事务执行能力。"""
self._repository = repository
self._async_executor = async_executor
def get(self, username: str, key: str) -> Any:
"""读取用户配置。"""
@@ -30,6 +39,14 @@ class UserConfigurationService:
"""写入用户配置。"""
return self._repository.set(username=username, key=key, value=value)
async def async_set(self, username: str, key: str, value: Any) -> Any:
"""异步写入用户配置,并等待数据库提交或回滚完成。"""
if self._async_executor is None:
raise RuntimeError("用户配置异步数据库执行端口尚未配置")
return await self._async_executor.run(
partial(self._repository.set, username=username, key=key, value=value)
)
_configured_user_configuration: UserConfigurationService | None = None