Found during the /plan-eng-review of #45.
render_page (backend/storage.py:79-82) checks the cache at :64 for the read, then unconditionally writes at :81-82 with a plain open(..., "wb"):
- Non-atomic. A reader can observe a half-written PNG under its final name.
- Raced. Two concurrent GETs of the same page both miss the cache and both write the same path.
#45 makes save_original / save_converted / save_filed / save_scanner_test_frame atomic via a new backend/atomic.py, and excludes page_cache from backups entirely — so this stopped being a backup bug. It is still a live serving bug: the user sees a broken image.
Fix: route the cache write through backend/atomic.py's atomic_write_bytes once #45 lands. Should be a two-line change at that point.
Related: #45, #46.
Found during the /plan-eng-review of #45.
render_page(backend/storage.py:79-82) checks the cache at:64for the read, then unconditionally writes at:81-82with a plainopen(..., "wb"):#45 makes
save_original/save_converted/save_filed/save_scanner_test_frameatomic via a newbackend/atomic.py, and excludespage_cachefrom backups entirely — so this stopped being a backup bug. It is still a live serving bug: the user sees a broken image.Fix: route the cache write through
backend/atomic.py'satomic_write_bytesonce #45 lands. Should be a two-line change at that point.Related: #45, #46.