fix(downloads): revive the worker cancel branch and guard terminal writes (B-sub-1)
The cancel route writes status 'canceled' but the supervisor compared against 'cancelled', so its "a route stopped it -> kill the child, free the asset" branch was dead code. A canceled job's child ran to completion and wrote 'done' unconditionally over the route's 'canceled'; since 'done' holds the asset but 'canceled' does not, a later delete released the asset a second time, dropping ref_count below the live holder count and deleting a file still in use. Add app/downloads/status.py as the single source of truth for the lifecycle literals (JobStatus StrEnum + the HOLDING / STOPPED_BY_ROUTE sets) and use it at the safety-critical sites: the supervisor stop check, the route cancel, and release_asset's holding set. Make the worker's terminal done/error writes conditional on the row still being 'running' so a child finishing just after a route cancel/pause can no longer resurrect it. Add the missing 'canceled' supervisor regression test. (The full literal sweep across the downloads surface is left for the E3 downloads owner-unification; this is the data-safety subset.)
This commit is contained in:
@@ -22,6 +22,7 @@ from app.db import get_db
|
||||
from app.downloads import edit as editmod
|
||||
from app.downloads import links as linksmod
|
||||
from app.downloads import formats, quota, service, storage
|
||||
from app.downloads.status import JobStatus
|
||||
from app.models import (
|
||||
DownloadJob,
|
||||
DownloadLink,
|
||||
@@ -544,9 +545,9 @@ def cancel_download(
|
||||
job_id: int, user: User = Depends(require_human), db: Session = Depends(get_db)
|
||||
) -> dict:
|
||||
job = _own_job(db, user, job_id)
|
||||
if job.status not in ("done", "canceled"):
|
||||
if job.status not in (JobStatus.DONE, JobStatus.CANCELED):
|
||||
service.release_asset(db, job) # release while the job still counts as holding
|
||||
job.status = "canceled"
|
||||
job.status = JobStatus.CANCELED
|
||||
db.commit()
|
||||
return _serialize_job(db, job)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user