v3.7.5 - Post-sync auto-rematch + hardened match-job error handling
✨ New Features
- DAT re-syncs now auto-rematch previously-scanned files. When a DAT re-sync wipes the match cache, the sync now snapshots the pre-wipe path list and enqueues a background
/dat/match-batch/jobagainst those paths. Before this,GET /dat/statswould readmatched=0, scanned=0immediately after a sync until the user manually browsed every affected directory. The stats counter now refreshes on its own within a few minutes of sync completion. schedule_match_job()helper. Extracted from the/dat/match-batch/jobHTTP handler so non-HTTP callers (like the post-sync hook) can reuse the same concurrency-guarded scheduling path. Works with or without a FastAPIBackgroundTasks.
🐛 Bug Fixes & Hardening
- Failure counting in
_run_match_job. Previously a dropped volume produced a misleading"complete, 0 matched"signal. Two new counters (errors+skips) now track real failures vs. policy skips. Whenerrors == totalthe job flips tofailedwith a"check volume accessibility"error message. - Mid-loop exception preserves counter context. Error message now includes
processed N/M, K error(s)so operators know how far the job got. - Programmer-error tracebacks surface. Two broad
except Exceptionblocks now uselogger.exception(ERROR level with full traceback) rather thanlogger.warning. - Background match-task exceptions surface too. Exceptions past
_run_match_job's owntry/finallyare now routed through the project logger instead of only appearing as asyncio's "Task exception was never retrieved" warning on GC. list_match_pathsfailure no longer leaks staged DATs. Snapshot failure is now best-effort; the DAT import stays durable.- Rematch
ImportErrorno longer silently swallowed. A missing-module deployment bug now fails the sync loudly. schedule_match_jobscheduling failure rolls back_active_match_job_id. Without this, future match jobs would return HTTP 409 forever after a failed schedule.- Canonical internal imports. Removed three
try: from services.x / except ImportError: from app.services.xfallback pairs that could silently absorb real circular-import bugs. Production-only feature-gate imports inarchive.py/disc_id.pyuntouched.
🧪 Tests
308 tests pass (+14 new since v3.7.3), covering the rematch hook, error counting, threshold behavior, traceback logging, scheduling-failure rollback, and snapshot-failure resilience.
⚠️ Upgrade Notes
- No action required. After restart, stale-DAT self-heal (v3.7.3) triggers if needed, and the follow-up rematch now happens automatically.
- Jobs panel: after a sync you'll see a
"DAT Match"external job tick through your previously-scanned files. If a volume is offline while it runs, the job finishes withfailed+"all N file(s) failed — check volume accessibility"instead of a misleading"0 matched"success.