"""Background file push — API returns immediately; progress via WebSocket.""" from __future__ import annotations import logging from typing import List, Optional logger = logging.getLogger("nexus.sync_push_runner") async def run_sync_files_background( *, server_ids: List[int], source_path: str, target_path: Optional[str], sync_mode: str, operator: str, batch_size: int, concurrency: int, batch_id: str, ) -> None: """Execute sync_files in an isolated DB session (not request-scoped).""" from server.application.services.sync_engine_v2 import SyncEngineV2 from server.infrastructure.database.audit_log_repo import AuditLogRepositoryImpl from server.infrastructure.database.push_schedule_repo import PushRetryJobRepositoryImpl from server.infrastructure.database.server_repo import ServerRepositoryImpl from server.infrastructure.database.session import AsyncSessionLocal from server.infrastructure.database.sync_log_repo import SyncLogRepositoryImpl try: async with AsyncSessionLocal() as session: engine = SyncEngineV2( server_repo=ServerRepositoryImpl(session), sync_log_repo=SyncLogRepositoryImpl(session), audit_repo=AuditLogRepositoryImpl(session), retry_repo=PushRetryJobRepositoryImpl(session), ) await engine.sync_files( server_ids=server_ids, source_path=source_path, target_path=target_path, sync_mode=sync_mode, operator=operator, batch_size=batch_size, concurrency=concurrency, batch_id=batch_id, ) except Exception: logger.exception("Background sync_files failed: batch_id=%s", batch_id) def schedule_sync_files(**kwargs) -> None: """Fire-and-forget push task on the running event loop.""" import asyncio asyncio.create_task( run_sync_files_background(**kwargs), name=f"sync_push:{kwargs.get('batch_id', '')}", )