mirror of
https://github.com/euzu/tuliprox.git
synced 2026-09-24 01:52:17 +02:00
Task 11, step 4: retention and a user delete can reach the same recording. `begin_deletion` stamps a task by overwriting `state` with the deleting marker and recording the real prior state in `deleting_previous_state`. A second pass then read `state` -- now `Cancelled` -- and derived the prior state from it, concluding that a Completed recording had been cancelled. That distinction decides which file the deletion owns. Completed owns the final file; Cancelled owns the `.partial`. So the second deletion claimed a path the recording does not own, unlinked that instead, and finalized -- removing the entry that named the real file while leaving the file itself on disk, referenced by nothing. `prior_terminal_state_runtime` now refuses a task that is already stamped. The caller gets `NotTerminal`, which the service maps to `InvalidState`, which retention already maps to `Skipped` -- with a comment saying "already in Deleting" that had never been true. The guard the surrounding code was written against now exists. Also covers step 1, which had no test for its sharpest case: a cancelled entry owns the `.partial`, so removing it while another entry is mid-transfer on the same media unlinks exactly the file being written. The transfer would stream into an unlinked inode and the remaining user would end with nothing. Its counterpart is pinned too -- with nobody else holding it, an abandoned partial is still cleaned up. Step 3 needed no work: non-terminal entries are already refused removal, and that is already tested.