Skip to content

Answer a revalidated GET with the cached body - #216

Merged
russwyte merged 1 commit into
mainfrom
http/conditional-cache
Oct 5, 2026
Merged

russwyte merged 1 commit into
mainfrom
http/conditional-cache

Conversation

@russwyte

@russwyte russwyte commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

A repeat GET in one JVM gets the body, not a bodiless 304.

The bug

HttpLookup remembered each URL's ETag and sent If-None-Match on the next GET to it, but it kept no body. A second fetch of the same URL in one sbt session got a 304 with nothing in it. That broke two callers:

  • zipxSnapshotAdvance failed after zipxSnapshotStatus on the pointer metadata both read. Found adopting the stack in heddle:
    zipx: lookup .../ascent-dom-facade_sjs1_3/0.11.0-SNAPSHOT/maven-metadata.xml: HTTP 304
    
  • Catalog lookups read a 304 as "no artifact by that name". So a second zipxDepUpdate in one session could drop a platform, or a whole row.

The fix

  • The cache holds the last answer with an ETag, per URL. A 304 to its own revalidation returns that answer, so no caller sees a 304 it did not ask for.
  • A caller's own tag still gets the real 304. A caller that passes its own ifNoneMatch gets the server's 304, as before.
  • MavenMetadata no longer reads a 304 as a miss. One can only reach it now as a real error.

Tests

  • HttpLookupSpec:
    • a repeat GET revalidates with the first ETag, and a 304 answers with the first body;
    • a caller's own If-None-Match gets the server's 304 back.
  • sbt "scalafmtAll; cleanFull; testFull": 122 suites passed.
  • zipxWorkflowCheck: every generated file up to date.
  • plugin/scripted: all 24 fixtures passed.

HttpLookup remembered each URL's ETag and sent If-None-Match on the next GET,
but kept no body, so a repeat fetch in one JVM got a bodiless 304.
zipxSnapshotAdvance after zipxSnapshotStatus failed on it ("HTTP 304"), and
catalog lookups read it as an artifact that is not there.

The cache now holds the last answer with an ETag per URL. A 304 to its own
revalidation returns that answer, so no caller sees a 304 it did not ask
for. A caller that passes its own If-None-Match still gets the server's 304.
@russwyte
russwyte merged commit 18880f7 into main Oct 5, 2026
13 checks passed
@russwyte
russwyte deleted the http/conditional-cache branch October 5, 2026 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant