fix(downloads): a file asked for again during an over-cap pass stays whatever the clock says

The eviction pass called a file freshly used only when its last-access stamp was later than the
pass's own clock. A hit stamped just before the pass began but committed after its SELECT, or
stamped by a clock that had stepped back (the test VM's does), read as old, and the file the user
had just asked for was evicted. The pass now keeps the stamp its SELECT saw and skips a file
whose stamp changed since.
This commit is contained in:
2026-11-14 19:05:43 +01:00
parent 0eca18bcb4
commit 36f9aefb76
2 changed files with 36 additions and 15 deletions
+22
View File
@@ -739,6 +739,28 @@ def test_a_file_asked_for_again_while_the_cache_is_over_its_cap_stays(
assert (_root / "old.mp4").exists()
@pytest.mark.parametrize("stamped", ["before_the_pass", "by_a_clock_that_stepped_back"])
def test_a_cache_hit_stamped_earlier_than_the_pass_still_keeps_the_file(
db, make_user, _root, monkeypatch, stamped
):
# A hit is a stamp that changed since the pass's SELECT. Compared with the pass's own clock, a
# hit stamped before the pass began (committed after its SELECT), or by a clock that had stepped
# back, read as old and the file the user just asked for went.
jold, jnew = _two_over_the_cap(db, make_user, _root)
seen = NOW - timedelta(days=9)
stamp = seen + (timedelta(hours=1) if stamped == "before_the_pass" else timedelta(days=9))
def asked_again(other, asset_id):
if asset_id == jold.asset_id:
other.get(MediaAsset, asset_id).last_access_at = stamp - timedelta(seconds=1)
_meanwhile(monkeypatch, asked_again, step="_relock_evictable")
_gc(db)
db.expire_all()
assert db.get(DownloadJob, jold.id) is not None
assert (_root / "old.mp4").exists()
def test_a_file_asked_for_while_its_cached_copy_is_freed_gets_a_fresh_one(db, make_user):
# The enqueue read the cached copy unlocked: freed meanwhile, its job pointed at a row that was gone
# (a foreign-key failure, a 500).