feat: add Caffeine cache adapter module#220
Open
vazarkevych wants to merge 1 commit into
Open
Conversation
Adds an optional growthbook-cache-caffeine Gradle module providing a Caffeine-backed GbCacheManager implementation: - CaffeineGbCacheManager with builder-configurable maximum size, expire-after-write TTL and stats recording. - CaffeineCacheOptions, CaffeineCacheEntry and CaffeineCacheStats supporting types. - README section documenting usage with GrowthBookClient options.
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.
Add Caffeine cache adapter (
growthbook-cache-caffeine)Summary
Adds a new optional Gradle module,
growthbook-cache-caffeine, that provides a Caffeine-backed implementation of the SDK'sGbCacheManager. It gives applications a production-ready, high-performance in-process cache for feature payloads — with bounded size, expiry, and optional statistics — without falling back to filesystem persistence.Design
maximumSize, default1000) or by total payload weight in bytes (maximumWeight). Weight is the recommended bound for the GrowthBook feature cache, since it stores a single large JSON payload per endpoint — so entry-count limits don't meaningfully constrain memory. AWeighermeasures each entry by the UTF-8 byte length of its payload; whenmaximumWeightis set it takes precedence overmaximumSize.expireAfterWriteandexpireAfterAccessdurations map onto Caffeine's eviction. Note that the SDK's reads (loadCache,getLastUpdatedMillis) count as accesses, soexpireAfterAccessonly expires entries that have been fully idle.CaffeineCacheEntryholding the payload and anupdatedAt(epoch millis) timestamp, recorded from an injectableClock.getLastUpdatedMillis()is backed by that timestamp, enabling the SDK's freshness-based refresh skipping.recordStats(true),stats()returns an immutableCaffeineCacheStatssnapshot (hits, misses, hit rate, evictions). This type deliberately does not leak Caffeine'sCacheStats, so callers (e.g. an SDK diagnostics layer) can read cache health without taking on a Caffeine dependency.null); genuine access failures are wrapped inFeatureCacheExceptionwith the offending key for context.Tickerallows deterministic expiry tests, andcleanUp()forces pending size/weight eviction on demand (Caffeine evicts asynchronously by default).Configuration (
CaffeineCacheOptions)maximumSize— entry-count bound (default1000).maximumWeight— total payload-byte bound; takes precedence overmaximumSize.expireAfterWrite/expireAfterAccess— optional eviction durations.recordStats— enable statistics recording (default off).clock/ticker— injectable for testing.Usage
Documentation
README.mdwith dependency coordinates and aGrowthBookClientusage example.Testing
CaffeineGbCacheManagerTest) cover save/load, last-updated tracking, cache miss, clear, size- and weight-based eviction, expiry (via injectedTicker), and statistics.Build / packaging
settings.gradle.sourceCompatibility/targetCompatibility = 1.8).com.github.ben-manes.caffeine:caffeine:2.9.3(asimplementation, so it is not leaked onto consumers' compile classpath).sourcesandjavadocjars to GitHub Packages, consistent with the existinglibmodule.