force kill job

This commit is contained in:
Mateusz Gruszczyński
2026-05-04 19:21:09 +02:00
parent dca7389a1a
commit e9940bf16c
3 changed files with 32 additions and 9 deletions

View File

@@ -152,6 +152,10 @@ def _run(job_id: str):
_emit("operation_started", {"job_id": job_id, "action": job["action"], "profile_id": profile["id"], "hashes": payload.get("hashes") or [], "hash_count": len(payload.get("hashes") or []), "bulk": len(payload.get("hashes") or []) > 1})
_emit("job_update", {"id": job_id, "status": "running", "attempts": attempts})
result = _execute(profile, job["action"], payload)
fresh = _job_row(job_id)
# Awaryjne anulowanie: jeżeli użytkownik anuluje zadanie w trakcie pracy, wynik nie nadpisuje statusu cancelled.
if fresh and fresh["status"] == "cancelled":
return
_set_job(job_id, "done", result=result, finished=True)
_emit("operation_finished", {"job_id": job_id, "action": job["action"], "profile_id": profile["id"], "hashes": payload.get("hashes") or [], "hash_count": len(payload.get("hashes") or []), "bulk": len(payload.get("hashes") or []) > 1, "result": result})
_emit("job_update", {"id": job_id, "status": "done", "result": result})
@@ -159,6 +163,9 @@ def _run(job_id: str):
fresh = _job_row(job_id) or {}
attempts = int(fresh.get("attempts") or 1)
max_attempts = int(fresh.get("max_attempts") or 2)
# Awaryjne anulowanie: wyjątek z anulowanego zadania nie przywraca go do retry ani failed.
if fresh and fresh.get("status") == "cancelled":
return
status = "pending" if attempts < max_attempts else "failed"
_set_job(job_id, status, str(exc), finished=(status == "failed"))
_emit("operation_failed", {"job_id": job_id, "action": job.get("action"), "profile_id": job.get("profile_id"), "hashes": payload.get("hashes") or [], "error": str(exc)})
@@ -226,8 +233,9 @@ def list_jobs(limit: int = 200, offset: int = 0):
def cancel_job(job_id: str) -> bool:
row = _job_row(job_id)
if not row or row["status"] not in {"pending", "failed"}:
if not row or row["status"] in {"done", "cancelled"}:
return False
# Awaryjne anulowanie: pending, running i failed można oznaczyć jako cancelled z poziomu użytkownika.
_set_job(job_id, "cancelled", finished=True)
_emit("job_update", {"id": job_id, "status": "cancelled"})
return True
@@ -239,6 +247,17 @@ def clear_jobs() -> int:
return int(cur.rowcount or 0)
def emergency_clear_jobs() -> int:
# Awaryjne czyszczenie: najpierw zamyka aktywne zadania jako cancelled, potem czyści całą listę job logów.
now = utcnow()
with connect() as conn:
conn.execute("UPDATE jobs SET status='cancelled', error='Emergency cancelled by user', finished_at=COALESCE(finished_at, ?), updated_at=? WHERE status IN ('pending', 'running', 'failed')", (now, now))
cur = conn.execute("DELETE FROM jobs")
deleted = int(cur.rowcount or 0)
_emit("job_update", {"status": "cleared", "emergency": True})
return deleted
def retry_job(job_id: str) -> bool:
row = _job_row(job_id)
if not row or row["status"] not in {"failed", "cancelled"}: