Repository navigation
Conversation
A fill that began before the source reported a key gone can finish after the eviction and write the old value back. That value lasts until the next refresh. Each eviction now writes a random generation for the key. A fill reads the generation before it fetches and writes through a compare-and-set script only if the generation is unchanged. Shadow writes compare against the shadow's own generation. Fills older than two minutes are not written, and generations expire after four minutes. Skipped fills set cache.fill_discarded on the span.
lucataco
force-pushed
the
lucataco/cache-generation-fencing
branch
from
November 3, 2026 16:16
5b3e0f9 to
e6a5f74
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #232, which is merged. This PR is one commit on
main.Why
After #232, a fill that began before the source reported a key gone can finish after the eviction and write the old value back. The value lasts until the next refresh, at most the fresh TTL, because that refresh evicts it again.
What changed
cache:gen:<name>:<key>, with a random value in the same script that deletes the data and freshness keys.cache.fill_discardedon its span togeneration_changed,generation_read_failed, ormax_age.Cost
GETper backend, and the write becomes anEVALinstead of aMULTIpipeline.EVALper backend.Keep this a draft until the extra Redis work per fill has been measured. Then decide whether closing the late-fill window is worth that cost.
Verification
go test -race -shuffle=on ./cachepasses, andgolangci-lintv2.1.5 reports no issues.