feat(gpu): re-process trigger to apply new crop detectors to the existing library (#1202)
The siglip/ccip backfills skip images that already have current-version regions, so adding crop detectors only affected NEW images — the back-catalogue would never be re-cropped. Add a reprocess trigger that resets every done/error job of a task back to pending, so the agent re-runs the FULL pipeline (figure detection + CCIP + concept/panel crops) over the whole library under the current detectors. - reprocess_gpu_jobs(task='ccip') task + POST /api/gpu/reprocess. - gpu store reprocess() + GpuAgentCard "Re-process library (re-detect + re-crop)" button with a confirm (it's heavy). - Test: a done job resets to pending (attempts cleared). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa
This commit is contained in:
@@ -96,6 +96,19 @@ async def backfill():
|
||||
return jsonify({"celery_task_id": r.id, "task": task}), 202
|
||||
|
||||
|
||||
@gpu_bp.route("/reprocess", methods=["POST"])
|
||||
async def reprocess():
|
||||
"""Reset every done/error job of `task` back to pending so the agent re-runs
|
||||
the WHOLE library under the current pipeline (e.g. after adding crop
|
||||
detectors). Heavy — the back-catalogue is otherwise skipped by the backfills."""
|
||||
body = await request.get_json(silent=True) or {}
|
||||
task = str(body.get("task") or "ccip")
|
||||
from ..tasks.ml import reprocess_gpu_jobs
|
||||
|
||||
r = reprocess_gpu_jobs.delay(task)
|
||||
return jsonify({"celery_task_id": r.id, "task": task}), 202
|
||||
|
||||
|
||||
# --- Agent (bearer token): lease / submit / heartbeat / fail ------------
|
||||
|
||||
@gpu_bp.route("/jobs/lease", methods=["POST"])
|
||||
|
||||
@@ -549,6 +549,37 @@ def recover_orphaned_gpu_jobs() -> int:
|
||||
return res.rowcount or 0
|
||||
|
||||
|
||||
@celery.task(name="backend.app.tasks.ml.reprocess_gpu_jobs")
|
||||
def reprocess_gpu_jobs(task_name: str = "ccip") -> int:
|
||||
"""Reset every done/error job of `task_name` back to pending so the agent
|
||||
re-runs the WHOLE library under the CURRENT pipeline — e.g. after adding crop
|
||||
detectors (#1202), re-cropping existing images. Heavy + operator-triggered;
|
||||
the back-catalogue won't otherwise re-process (the backfills skip images that
|
||||
already have current-version regions). Returns the number reset."""
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from sqlalchemy import update
|
||||
|
||||
from ..models import GpuJob
|
||||
|
||||
SessionLocal = _sync_session_factory()
|
||||
with SessionLocal() as session:
|
||||
now = datetime.now(UTC)
|
||||
res = session.execute(
|
||||
update(GpuJob)
|
||||
.where(
|
||||
GpuJob.task == task_name,
|
||||
GpuJob.status.in_(["done", "error"]),
|
||||
)
|
||||
.values(
|
||||
status="pending", attempts=0, lease_token=None, leased_at=None,
|
||||
lease_expires_at=None, updated_at=now,
|
||||
)
|
||||
)
|
||||
session.commit()
|
||||
return res.rowcount or 0
|
||||
|
||||
|
||||
@celery.task(
|
||||
name="backend.app.tasks.ml.scheduled_ccip_auto_apply",
|
||||
soft_time_limit=1800, time_limit=2100,
|
||||
|
||||
Reference in New Issue
Block a user