60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
|
|
"""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', '')}",
|
||
|
|
)
|