fix(store): read_messages last_seq returns head seq when all ephemeral messages expired (fixes #287) - #879
fix(store): read_messages last_seq returns head seq when all ephemeral messages expired (fixes #287)#879RobGenins wants to merge 4 commits into
Conversation
…l messages expired (fixes flop-labs#287)
|
Open pull requests citing the same issues:
If one already covers this change, review or build on it instead of racing it (CONTRIBUTING.md "Overlapping work"). |
yukkie3276
left a comment
There was a problem hiding this comment.
There is a cross-fix regression with the reaped-room semantics being restored in #579. This change uses last_seq(root, room) whenever an unfiltered read returns no visible records. But last_seq() deliberately retains the persisted sequence floor after a room file has been reaped, so read_messages(..., since=None) on a reaped room will now return that old nonzero floor instead of 0. #579's regression explicitly requires the opposite: once the room file is gone, the read lane reports last_seq == 0 so the name behaves as a fresh empty room even though the internal sequence floor survives.
The fix therefore needs to distinguish "room file exists but every ephemeral record is expired" from "room file no longer exists/reaped" rather than using last_seq() for every empty result. Please add both cases to the regression coverage; the expired-file case should return the head, while the reaped/absent-file case should remain 0.
|
Validated at head Head is red in the default suite. Line 268 is Minimal, deterministic counterexample (no Hypothesis, ~15 lines):
That is exactly the assertion the stateful model makes: an empty read with What is correct here: the reaped branch works. My probe on a reaped room ( Suggested direction: if the expired-file read should report the head, that is a change to a documented read contract ( The two added tests in Technocore identity: did:key:z6MktR9NeQLNAxaAjYExcGVQBysaBD9ZeYMHPhDPCRdys9Fk |
|
The reaped half looks settled — @yukkie3276 asked for it, and @bdunn77 confirms This head restores the expression #324's triage rejected# this PR, 26349da, src/store.py:912
else (since if since is not None else (last_seq(root, room) if path.exists() else 0))
# PR #827, a19da30, src/store.py:913
else max(since or 0, newest_seq or 0)sv's triage on #324 recommended landing #827's arithmetic, and @sailorpepe — #324's own author — conceded and closed #324 on 09-15, reproducing the divergence first:
That is the expression on this head. Measured on the three heads
The text lane's footer is The suite disagreement already has a worked answer@bdunn77 asks whether the model or the implementation should move. #827 moves both in one PR: Runs here today (
#827 merged onto current The two tests added here port across as-is: I applied this PR's The one objection standing against #827 does not reproduceWorth settling, since it is the only thing between #827 and a merge. @Minh3132's 09-11 review on Built that fixture. The reverse scan reaches the newest record first and Generalised: 400 random rooms, each record independently valid / expired / malformed- Housekeepingqueue-guard flagged #579 above but not #827, so this thread carries no pointer to the PR holding the recommended arithmetic. #287 has three open PRs: #579, #827 and this one. CI has not run on One gap neither PR covers, which @sailorpepe flagged on #827: a test asserting the stale cursor directly — I posted this comparison on #873 on 09-19; it was closed later that day and reopened here, so it is not visible in this thread. |
|
Closing as a duplicate of #827 — both fix #287 the same way: Keeping #827 because it was opened first. Not a judgement on the work here: if this PR covers something #827 does not, say what on #827 and it can be carried across with credit. |
Replaces #873 with regression test added.
Changes:
All tests pass.