refactor: make subscription lifecycle events durable

This commit is contained in:
jxxghp
2026-08-22 07:43:41 +08:00
parent 8f94fd620d
commit c5de1c7b1b
27 changed files with 1106 additions and 230 deletions
+52 -18
View File
@@ -1,17 +1,36 @@
"""订阅领域的请求级 command/query 依赖。"""
from typing import Any, cast
from fastapi import BackgroundTasks, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Session
from app.adapters.external.server import MoviePilotServerHelper
from app.api.context import (
get_subscription_history_repository,
get_subscription_outbox,
get_subscription_repository,
get_subscription_transaction,
)
from app.api.data import get_async_db, get_db
from app.api.dependencies.data import repository, transaction
from app.api.dependencies.data import repository
from app.application.outbox import AsyncOutboxTransaction
from app.application.scheduling import Scheduler
from app.application.servarr import ServarrSubscriptionService
from app.application.subscription.delete import DeleteSubscribeCommand
from app.application.subscription.delete import (
AsyncUnitOfWork as DeleteUnitOfWork,
DeleteSubscribeCommand,
SubscribeDeletionRepository,
)
from app.application.subscription.identity import DeleteSubscriptionsByIdentityCommand
from app.application.subscription.mutation import SubscriptionMutationService
from app.application.subscription.identity import SubscribeIdentityDeletionRepository
from app.application.subscription.mutation import (
AsyncUnitOfWork as MutationUnitOfWork,
SubscriptionHistoryMutationRepository,
SubscriptionMutationRepository,
SubscriptionMutationService,
)
from app.application.subscription.query import SubscriptionQueryService
from app.application.subscription.search import SearchSubscriptionsCommand
from app.runtime.events import eventmanager
@@ -20,25 +39,29 @@ from app.schemas.types import EventType
async def _publish_subscribe_deleted(
subscribe_id: int,
subscribe_info: dict,
payload: dict[str, Any],
) -> None:
"""通过宿主事件总线发布已提交的订阅删除事件。"""
await eventmanager.async_send_event(
EventType.SubscribeDeleted,
{"subscribe_id": subscribe_id, "subscribe_info": subscribe_info},
)
await eventmanager.async_send_event(EventType.SubscribeDeleted, payload)
async def _publish_subscribe_modified(payload: dict[str, Any]) -> None:
"""通过宿主事件总线发布已提交的订阅修改事件。"""
await eventmanager.async_send_event(EventType.SubscribeModified, payload)
def get_delete_subscribe_command(
db: AsyncSession = Depends(get_async_db),
repository_port: object = Depends(get_subscription_repository),
unit_of_work: object = Depends(get_subscription_transaction),
outbox: AsyncOutboxTransaction = Depends(get_subscription_outbox),
) -> DeleteSubscribeCommand:
"""组装请求级订阅删除用例及其具体适配器。"""
return DeleteSubscribeCommand(
repository=repository("subscribe", db),
unit_of_work=transaction("async", db),
repository=cast(SubscribeDeletionRepository, repository_port),
unit_of_work=cast(DeleteUnitOfWork, unit_of_work),
publish_deleted=_publish_subscribe_deleted,
report_deleted=MoviePilotServerHelper.sub_done_async,
outbox=outbox,
)
@@ -54,14 +77,17 @@ def _log_subscribe_deleted_event_error(
def get_delete_subscriptions_by_identity_command(
db: AsyncSession = Depends(get_async_db),
repository_port: object = Depends(get_subscription_repository),
unit_of_work: object = Depends(get_subscription_transaction),
outbox: AsyncOutboxTransaction = Depends(get_subscription_outbox),
) -> DeleteSubscriptionsByIdentityCommand:
"""组装请求级按媒体身份删除订阅用例。"""
return DeleteSubscriptionsByIdentityCommand(
repository=repository("subscribe", db),
unit_of_work=transaction("async", db),
repository=cast(SubscribeIdentityDeletionRepository, repository_port),
unit_of_work=cast(DeleteUnitOfWork, unit_of_work),
publish_deleted=_publish_subscribe_deleted,
handle_event_error=_log_subscribe_deleted_event_error,
outbox=outbox,
)
@@ -98,12 +124,20 @@ def get_subscription_query_service(
def get_subscription_mutation_service(
db: AsyncSession = Depends(get_async_db),
repository_port: object = Depends(get_subscription_repository),
history_repository: SubscriptionHistoryMutationRepository = Depends(
get_subscription_history_repository
),
unit_of_work: object = Depends(get_subscription_transaction),
outbox: AsyncOutboxTransaction = Depends(get_subscription_outbox),
) -> SubscriptionMutationService:
"""组装异步订阅写服务。"""
return SubscriptionMutationService(
repository=repository("subscribe", db),
history_repository=repository("subscribe_history", db),
repository=cast(SubscriptionMutationRepository, repository_port),
history_repository=history_repository,
unit_of_work=cast(MutationUnitOfWork, unit_of_work),
outbox=outbox,
publish_modified=_publish_subscribe_modified,
)