Repository navigation
TierCache 1.2.0
[1.2.0] - 2026-09-20
Added
tiercache.async-executor-threads/TierCacheFactory.Builder.asyncExecutorThreads(int)(also on the Kotlin DSL,KTierCacheFactory.Builder, andReactorCacheFactory.Builder): thread cap for the bounded async executor, defaultmax(4, availableProcessors).docs/sizing-and-ttl.md: journal-capacity sizing guidance.
Changed
- The async executor is now bounded with a bounded queue (10,000): previously
AsyncTierCacheoperations ran on an unbounded cached thread pool shared with background revalidation. Under saturation, submissions fail theirCompletionStagewithRejectedExecutionExceptioninstead of growing threads without bound. Background SWR/XFetch revalidation runs on its own small bounded pool. SeeUPGRADING.mdfor the saturation behavior change. - Docs accuracy: the recovery description no longer claims L1 is "never" flushed (replay within the journal window; flush on window overflow, signalled via log/metric/listener). README now states that
@Cacheableload coalescing requiressync = trueand that null caching is opt-in.
Fixed
- Cross-instance write ordering: versions were per-instance counters starting at 1, so a freshly started instance's writes (and evicts) could be rejected as stale against a long-running instance's earlier writes on the same key. Versions are now time-ordered (wall-clock hybrid sequence); the wire format and Redis scripts are unchanged. See
UPGRADING.mdfor the rolling-upgrade note and the clock-sync expectation. - Reconnect replay for Spring/Micronaut-wired caches: the invalidation journal was written under the namespaced cache name while the recovery path replayed the logical name, so missed invalidations were never replayed and stale L1 entries survived until TTL. The journal now follows the logical cache name in all wirings.
Verify
Artifacts are signed (Sigstore keyless) and attested:
gh attestation verify <jar> --repo cramen/tier_cache
SBOM attached (tiercache-sbom.json). Maven coordinates: io.github.cramen:<module>:1.2.0.