fix(downloads): rewire MaintenanceMenu to the downloads pipeline
The maintenance dropdown in Subscriptions → Downloads was wired to the
filesystem-import pipeline (POST /api/import/retry-failed +
POST /api/import/clear-stuck) — the subtitles even said so ("Re-enqueue
every failed import task"), but it was contextually misplaced. From the
Downloads view "Retry failed" queued nothing the operator could see
because the action operated on import_task rows, not download_event
rows. Import-pipeline maintenance is already reachable from Settings →
Imports (ImportTaskList.vue), so removing the import wiring loses
nothing.
Rewired:
- "Retry failed" → bulk-retries the failing-sources list, same loop as
FailingSourcesCard's RETRY ALL (sourcesStore.checkNow per source).
Subtitle now matches: "Re-queue every currently failing source".
- "Force recovery sweep" → triggers recover_stalled_download_events on
demand via a new POST /api/downloads/recover-stalled endpoint. The
sweep also runs every 5 min on Beat; this is the manual fallback so
the operator doesn't have to wait for the next tick to clear newly
stranded events.
MaintenanceMenu is now stateless — emits retry-failed and recover-
stalled. DownloadsTab owns the handlers (reuses the existing
onRetryAll; new onRecoverStalled with a delayed refresh so swept rows
land in the failing rollup).
Operator-flagged 2026-05-29 — "the retry failed button in the
maintenance dropdown doesn't appear to queue anything but manual
requeues works."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -187,3 +187,20 @@ async def get_download(event_id: int):
|
||||
return jsonify({"error": "not_found"}), 404
|
||||
event, source, artist = row
|
||||
return jsonify(_detail_record(event, source, artist))
|
||||
|
||||
|
||||
@downloads_bp.route("/recover-stalled", methods=["POST"])
|
||||
async def recover_stalled():
|
||||
"""Trigger the recover_stalled_download_events sweep on demand.
|
||||
|
||||
The same sweep runs every 5 min via Beat (see celery_app.beat_schedule);
|
||||
this endpoint exists so the operator can force-clear stuck pending/
|
||||
running download_events from the Subscriptions → Downloads maintenance
|
||||
menu without waiting for the next scheduled tick.
|
||||
"""
|
||||
# Local import: avoids registering maintenance tasks during blueprint
|
||||
# import (Celery task discovery races with the API import otherwise).
|
||||
from ..tasks.maintenance import recover_stalled_download_events
|
||||
|
||||
recover_stalled_download_events.delay()
|
||||
return jsonify({"queued": True}), 202
|
||||
|
||||
Reference in New Issue
Block a user