68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
"""
|
||
回忆录后台处理器:debounce 聚合后派发 Celery 任务
|
||
实际回忆录生成由 memoir_tasks.process_memoir_segments 调用 MemoirOrchestrator 完成
|
||
"""
|
||
|
||
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
|