mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 04:20:45 +08:00
Periodic vendor-aware CLI sync stores zlib snapshots in Postgres with dashboard, retry, and config viewer under Network Management. Co-authored-by: Cursor <cursoragent@cursor.com>
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
"""Startup recovery for interrupted config-sync cycles."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from .config_sync_runner import dispatch_cycle
|
|
from .config_sync_service import finalize_cycle, sync_cycle_progress
|
|
from .models import ConfigSyncCycle, ConfigSyncTask
|
|
from datetime import datetime
|
|
|
|
_log = logging.getLogger("netx.config_sync.recovery")
|
|
|
|
|
|
def recover_config_sync_on_startup(db: Session) -> int:
|
|
"""
|
|
Mark orphaned running tasks as fail(orphan_recovered), then resume pending
|
|
tasks for cycles still marked running/paused.
|
|
"""
|
|
cycles = (
|
|
db.query(ConfigSyncCycle)
|
|
.filter(ConfigSyncCycle.status.in_(("running", "paused", "pending")))
|
|
.all()
|
|
)
|
|
resumed = 0
|
|
for cycle in cycles:
|
|
cycle_id = str(cycle.id)
|
|
orphans = (
|
|
db.query(ConfigSyncTask)
|
|
.filter(ConfigSyncTask.cycle_id == cycle_id, ConfigSyncTask.status == "running")
|
|
.all()
|
|
)
|
|
for task in orphans:
|
|
task.status = "fail"
|
|
task.message = "orphan_recovered"
|
|
task.ended_at = datetime.utcnow()
|
|
if orphans:
|
|
db.commit()
|
|
_log.info("config_sync recovery cycle=%s orphaned_tasks=%s", cycle_id, len(orphans))
|
|
|
|
sync_cycle_progress(db, cycle_id)
|
|
db.refresh(cycle)
|
|
|
|
if str(cycle.status) == "paused":
|
|
continue
|
|
|
|
pending = (
|
|
db.query(ConfigSyncTask)
|
|
.filter(ConfigSyncTask.cycle_id == cycle_id, ConfigSyncTask.status == "pending")
|
|
.count()
|
|
)
|
|
if pending <= 0:
|
|
if str(cycle.status) in ("running", "pending"):
|
|
finalize_cycle(db, cycle_id)
|
|
continue
|
|
|
|
if str(cycle.status) == "pending":
|
|
cycle.status = "running"
|
|
if not cycle.started_at:
|
|
cycle.started_at = datetime.utcnow()
|
|
db.commit()
|
|
|
|
n = dispatch_cycle(cycle_id)
|
|
resumed += n
|
|
_log.info("config_sync recovery resumed cycle=%s pending=%s", cycle_id, n)
|
|
return resumed
|