Repository navigation
Invariant 2 promised something no cache can deliver - #51
Conversation
It said a revisit costs zero remote round trips, with no qualification. Once a listing is not trusted, "is this still the current version?" cannot be answered without asking — so outside the freshness window a revisit costs a listing refresh by construction, and no amount of caching changes that. Measured against a real host: a revisit straight after a load costs zero, and the same revisit three seconds later costs ten. That is the window working, not the cache failing. The claim now says which window it is true in, and what it costs outside it. It is still a strong claim and it is the one that holds. The e2e now checks it over the real transport. The unit test for this holds a fake remote and a three-byte fixture, so it revisits instantly and cannot see the window at all — it would pass with any TTL, including none. Neutered against a zero TTL the new check fails, which the unit test does not. It navigates away and back rather than reloading. A reload tells the browser to re-fetch; measuring that would not be measuring this claim. Found while investigating what looked like a much worse bug, which it was not: the daemon's cache does exactly what it says when driven directly, and two of the numbers that suggested otherwise were instrument error. The detail is in #49. Signed-off-by: Souta <shimozono-sota631@g.ecc.u-tokyo.ac.jp>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…ng it Two faults, both mine, both the same shape: the instrument was part of what it measured. It sampled the round-trip count off `GET /_control/hosts`, which runs `ssh -G` once per configured host. Taken either side of a page load, that call takes long enough to expire the listings being measured. It passed against a real host and failed in CI, which is the worst way round. The count is now on `hello`, the cheap route, which is two milliseconds. Then, with a fast counter, it failed everywhere — because the slow call had been acting as a settling delay, and without it the first load's tail landed in the second load's bucket. The deeper fault is that it asserted something nobody had established. Invariant 2 is about a request. "A whole browser page costs nothing the second time" is a larger claim, and it is false: against a real host this fixture costs four round trips on a browser revisit, because a page fetches things no HTML scan can see and the freshness window is a wall clock a test has to race. So it now checks what invariant 2 says, over the real transport, where it is exact: a second read costs nothing, a range out of a held body costs nothing, and the browser's own validator is answered here with a 304 rather than there. Against a zero TTL all three fail; the unit tests pass unchanged, which is the point of having these as well. Signed-off-by: Souta <shimozono-sota631@g.ecc.u-tokyo.ac.jp>
Pushed a fix, and the reason is worth writing downThe check I added here failed in CI while passing against a real host. Twice over, the instrument was part of what it measured. It sampled the counter off With a fast counter it then failed everywhere, because the slow call had been acting as a settling delay. Without it, the first load's tail landed in the second load's bucket. And underneath both: it asserted something nobody had established. Invariant 2 is a claim about a request. "A whole browser page costs nothing the second time" is a larger claim and it is false — against a real host this fixture costs four round trips on a browser revisit, because a page fetches things no HTML scan can see, and the freshness window is a wall clock a test has to race. So the check now tests what invariant 2 actually says, over the real transport, where it is exact: Neutered against This is the third time today that a measurement here turned out to perturb its subject — the other two are in #49. The pattern is worth naming: a counter you cannot read without disturbing is not a counter. |
The claim was too strong
The second half is true and verified. The first half is true inside the freshness window and cannot be true outside it: once a listing is not trusted, "is this still the current version?" cannot be answered without asking.
Measured against a real host over SSH:
That is the window doing its job. The README now says which window the claim holds in, and what a revisit costs outside it.
The e2e now checks it over the real transport
a_revisit_costs_no_remote_round_tripsholds aFakeRemoteand a three-byte fixture. It revisits instantly, so it never meets the freshness window — it would pass with any TTL, including none.The new check drives a real browser against whatever host the run is pointed at, reads the round-trip count off
GET /_control/hosts, and asserts a revisit adds nothing. Neutered againstDEFAULT_TTL = Duration::ZERO:The unit test passes unchanged under that same neutering.
It navigates away and back rather than calling
reload(). A reload tells the browser to re-fetch, and measuring it would not be measuring this claim.What this came out of
An investigation into what looked like a much worse bug — "a revisit costs 13–30 round trips on every real site". It was not. Written up in full in #49, but in short:
page.reload()is not a revisit.request.headers()is the pre-flight snapshot and misses headers the browser adds. The 304s in the responses prove revalidation was happening.I also built the listing TTL as an idle window rather than an absolute one, and reverted it: it passed neutered tests but made no measurable difference, and moved the Documenter page in the wrong direction. Shipping a public API change on an argument the measurement does not support is not how this repository works.
Verified
cargo fmt --check,clippy -D warnings, 177 tests, and the full e2e against a real host: all checks pass.