The job worker set status = "done" first, then removed the job's upload, and only set finished_at in a finally block after that. A client polling for done, whether the web UI or the tests' wait_status, could see a finished job with its upload still on disk and finished_at: null. That's why test_upload_dir_cleaned_up_after_success, test_job_has_timestamps and test_cover_upload_kept_after_success failed at random, and why CI kept going red for no reason.
Fix
The worker records the outcome (done, or failed with its error) and publishes status, error and finished_at together, under the lock, as its last step, after the upload cleanup. Cleanup moves inside the try. _cleanup_uploads never raises, so it can't fail a job that otherwise succeeded, and its docstring now says that instead of relying on the old ordering.
Testing
New regression test: upload cleanup is slowed by 0.3s, and a job seen as done must already have finished_at set and its upload removed. It fails every time against main and passes with this change.
The full test_web.py suite passed 5 runs in a row. It used to fail roughly once every two or three runs.
Full suite passes, except test_version (needs the package installed, as CI does).
**Summary generated by LLM agent**
Fixes #18.
The job worker set `status = "done"` first, then removed the job's upload, and only set `finished_at` in a `finally` block after that. A client polling for `done`, whether the web UI or the tests' `wait_status`, could see a finished job with its upload still on disk and `finished_at: null`. That's why `test_upload_dir_cleaned_up_after_success`, `test_job_has_timestamps` and `test_cover_upload_kept_after_success` failed at random, and why CI kept going red for no reason.
## Fix
The worker records the outcome (`done`, or `failed` with its error) and publishes `status`, `error` and `finished_at` together, under the lock, as its last step, after the upload cleanup. Cleanup moves inside the `try`. `_cleanup_uploads` never raises, so it can't fail a job that otherwise succeeded, and its docstring now says that instead of relying on the old ordering.
## Testing
- New regression test: upload cleanup is slowed by 0.3s, and a job seen as `done` must already have `finished_at` set and its upload removed. It fails every time against `main` and passes with this change.
- The full `test_web.py` suite passed 5 runs in a row. It used to fail roughly once every two or three runs.
- Full suite passes, except `test_version` (needs the package installed, as CI does).
The worker set status "done" before removing the job's upload and before
setting finished_at, so a client polling for done could see the upload
still there and finished_at null. Record the outcome and publish status,
error and finished_at together, under the lock, as the last step.
branderson
approved these changes 2026-10-11 00:21:57 -07:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary generated by LLM agent
Fixes #18.
The job worker set
status = "done"first, then removed the job's upload, and only setfinished_atin afinallyblock after that. A client polling fordone, whether the web UI or the tests'wait_status, could see a finished job with its upload still on disk andfinished_at: null. That's whytest_upload_dir_cleaned_up_after_success,test_job_has_timestampsandtest_cover_upload_kept_after_successfailed at random, and why CI kept going red for no reason.Fix
The worker records the outcome (
done, orfailedwith its error) and publishesstatus,errorandfinished_attogether, under the lock, as its last step, after the upload cleanup. Cleanup moves inside thetry._cleanup_uploadsnever raises, so it can't fail a job that otherwise succeeded, and its docstring now says that instead of relying on the old ordering.Testing
donemust already havefinished_atset and its upload removed. It fails every time againstmainand passes with this change.test_web.pysuite passed 5 runs in a row. It used to fail roughly once every two or three runs.test_version(needs the package installed, as CI does).