"""回忆录后台任务聚合:debounce 后派发 process_memoir_segments(feature 层)。""" from __future__ import annotations from typing import Dict, List from app.core.logging import get_logger from app.core.task_tracker import task_tracker logger = get_logger(__name__) class BackgroundTaskRunner: def __init__(self, debounce_seconds: int = 5) -> None: self.debounce_seconds = debounce_seconds self._pending: Dict[str, List[str]] = {} self._timers: Dict[str, object] = {} async def _submit_task(self, user_id: str, segment_ids: List[str]) -> str | None: try: from app.tasks.memoir_tasks import process_memoir_segments result = process_memoir_segments.delay(user_id, segment_ids) task_id = result.id await task_tracker.add_task(user_id, task_id, "memoir") logger.info( "已提交 Celery 任务: user_id=%s, task_id=%s, segments=%s", user_id, task_id, len(segment_ids), ) return task_id except Exception as e: logger.error("提交 Celery 任务失败: %s", e) return None async def queue_message(self, user_id: str, segment_id: str) -> None: import asyncio self._pending.setdefault(user_id, []).append(segment_id) if user_id in self._timers: self._timers[user_id].cancel() async def delayed_submit(): try: await asyncio.sleep(self.debounce_seconds) segment_ids = self._pending.pop(user_id, []) if segment_ids: await self._submit_task(user_id, segment_ids) except asyncio.CancelledError: pass except Exception as e: logger.error("延迟提交任务失败: %s", e) self._timers[user_id] = asyncio.create_task(delayed_submit()) async def flush_pending(self, user_id: str) -> str | None: if user_id in self._timers: self._timers[user_id].cancel() del self._timers[user_id] segment_ids = self._pending.pop(user_id, []) if segment_ids: return await self._submit_task(user_id, segment_ids) return None