Skip to main content

mark_reaped

Function mark_reaped 

Source
pub async fn mark_reaped(conn: &mut PgConnection, id: Uuid) -> ModelResult<bool>
Expand description

Retires an upload, keeping the row so a submit naming it answers upload_expired instead of the misleading unknown_upload. Idempotent, so a run retrying a failed object delete can call it again.

Re-checks that no submission has come to reference the upload since get_reapable listed it, and reports false if one has. That re-check plus the row lock lock_for_exercise_and_user takes is what stops a reap from landing in the middle of a submit and destroying its files.

The lock is taken in a statement of its own, and that ordering is the whole point. Under READ COMMITTED a statement’s snapshot is fixed when the statement starts, and Postgres refreshes only the row an UPDATE locks — never the rows its subqueries read. So a single locking UPDATE blocks on the submit’s lock, unblocks, and then evaluates NOT EXISTS against a snapshot from before the submit committed: it finds no submission and reaps the files of a submission that already answered 200. Locking first makes the UPDATE a later statement, so its snapshot includes that commit.