Repository navigation
[release] feat(lib-cache-tiered-redis): add optional L1 TTL (1.2.0) - #168
Merged
Merged
Conversation
An L1 entry lived as long as the value's own TTL, so an instance holding a key in L1 never saw a newer value another instance wrote to L2 until that TTL passed. Caches whose values are refreshed periodically under a long TTL (e.g. a cron rewriting a 7-day entry hourly) were left serving the first copy on every instance but the writer. AbstractTieredCache gains a protected getL1Ttl() hook, null by default so existing caches are unchanged. When set, the L1 Caffeine cache expires entries after that duration and the next read rehydrates from L2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Paolo Di Tommaso <paolo.ditommaso@gmail.com>
jonmarti
approved these changes
Oct 23, 2026
jonmarti
left a comment
Contributor
There was a problem hiding this comment.
@pditommaso, approving:
- with no L1 TTL the cache is built exactly as before;
- the L1 TTL only bounds how long a copy is served locally (the value's own
expiresAtcheck still applies); - the removal listener, which now also fires on L1 expiry, only logs.
The first new test can't pass without the hook, since the reader would keep serving its first copy, as the second test pins. Two non-blocking notes inline.
…tion.ZERO Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Addressed both review notes in 69de38d:
|
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.
What changes
Adds an optional L1 TTL to
AbstractTieredCache, so a value rewritten in Redis by one instance reaches every other instance within a bounded time.Today an L1 (Caffeine) entry is kept for as long as the value's own TTL. An instance that holds a key in L1 does not see a newer value another instance writes to L2 until that TTL passes. That's fine for values written once, but it breaks caches whose values are refreshed during their lifetime. For example, sched's CloudInfo snapshot store (seqeralabs/sched#1742) keeps each region's catalogue under a 7-day TTL as an outage safety net, and a cron on one pod rewrites it every hour. Without an L1 bound, every pod except the writer would keep serving its first copy for up to 7 days.
How
protected Duration getL1Ttl()hook, returningnullby default, so existing caches behave exactly as before.expireAfterWrite(l1Ttl), and the next read after expiry rehydrates from L2. An entry's L1 lifetime is the shorter of the L1 TTL and the value's own TTL; L2 expiry is unchanged.[release]).Testing
./gradlew :lib-cache-tiered-redis:testpasses (Redis Testcontainer). Two new cases inAbstractTieredCacheTest:🤖 Generated with Claude Code