Cocache
Skill Ahoo-Wang/skills/plugins/ahoo-cocache-skills/skills/cocache
Use when building or modifying Java/Kotlin applications with CoCache two-level distributed coherent caching. Invoke for @CoCache cache interfaces, @JoinCacheable composition, Redis-backed coherence, Spring Boot integration, cache proxy behavior, custom cache backends, cache breakdown protection, or CoCache TCK tests.From its SKILL.md
npx -y skills add Ahoo-Wang/skills --skill cocacheAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 7 commands, including `./gradlew check` and 6 more.
SKILL.md
4.8 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
CoCache Development Guide
CoCache is a Java/Kotlin two-level distributed coherent cache framework:
- L2 client-side cache: local Map, Guava, or Caffeine cache.
- L1 distributed cache: Redis-backed shared cache.
- Coherence:
CacheEvictedEventBuspublishes evictions so peer instances invalidate local entries.
Start Here
Choose the smallest reference that fits the request:
| Task | Read |
|---|---|
| Add CoCache to a Spring or Spring Boot app | references/setup.md |
Compose cached values with @JoinCacheable | references/join-cache.md |
| Write or update tests | references/testing.md |
| Implement a custom L1/L2 cache, event bus, key converter, or source | references/custom-implementation.md |
Repository Rules
When editing this repository, follow AGENTS.md:
- Use
me.ahoo.test.asserts.assertand.assert()in Kotlin tests; do not use AssertJassertThat(). - Extend the TCK specs in
cocache-testfor cache implementations. - Ask before changing
cocache-apipublic interfaces or adding dependencies. - Run the relevant Gradle checks before finishing; prefer
./gradlew checkfor broad changes.
Core Model
Define one cache interface per cache domain. The interface extends Cache<K, V>, is annotated with @CoCache, and is registered through @EnableCoCache. CoCache creates a proxy at runtime.
@CoCache(keyPrefix = "user:", ttl = 120)
@GuavaCache(maximumSize = 1_000_000, expireAfterAccess = 120, expireUnit = TimeUnit.SECONDS)
interface UserCache : Cache<String, User>
@SpringBootApplication
@EnableCoCache(caches = [UserCache::class])
class App
Use caches through Kotlin operators: cache[key], cache[key] = value, cache.evict(key), and cache.getCache(key) when CacheValue metadata is required.
Extension Points
CoCache auto-configures defaults, but each component can be overridden:
- Per cache, define named beans such as
UserCache.CacheSource,UserCache.ClientSideCache,UserCache.KeyConverter, orUserCache.JoinKeyExtractor. - Globally, define beans by type; auto-configured beans use
@ConditionalOnMissingBean. - For data loading, implement
CacheSource<K, V>.loadCacheValue(key)and returnDefaultCacheValue.forever(value),DefaultCacheValue.ttlAt(value, ttl), or boundedDefaultCacheValue.missingGuard(ttl, amplitude)values.
Testing Pattern
CoCache provides abstract specs in cocache-test for compatibility coverage:
CacheSpec<K,V>for base cache behavior.ClientSideCacheSpec<V>for L2 caches.DistributedCacheSpec<V>for L1 caches.DefaultCoherentCacheSpec<K,V>for two-level coherent cache behavior and cache breakdown protection.MultipleInstanceSyncSpec<K,V>andCacheEvictedEventBusSpecfor cross-instance coherence and event buses.
Use the repo's createCacheEntry(): Pair<K, V> contract:
class MyDistributedCacheTest : DistributedCacheSpec<String>() {
override fun createCache(): DistributedCache<String> {
return MyDistributedCache()
}
override fun createCacheEntry(): Pair<String, String> {
return UUID.randomUUID().toString() to "test_value"
}
}
Key Classes
| Class | Module | Purpose |
|---|---|---|
Cache<K,V> | cocache-api | Base cache interface |
CoherentCache<K,V> | cocache-core | Two-level cache engine |
DefaultCoherentCache | cocache-core | Default implementation |
ClientSideCache<V> | cocache-api | L2 local cache interface |
MapClientSideCache | cocache-core | ConcurrentHashMap impl |
GuavaClientSideCache | cocache-core | Guava Cache impl |
CaffeineClientSideCache | cocache-core | Caffeine Cache impl |
DistributedCache<V> | cocache-core | L1 distributed cache interface |
RedisDistributedCache | cocache-spring-redis | Redis impl |
CacheSource<K,V> | cocache-api | Data source loader |
CacheEvictedEventBus | cocache-core | Event bus for coherence |
RedisCacheEvictedEventBus | cocache-spring-redis | Redis Pub/Sub impl |
JoinCache<K1,V1,K2,V2> | cocache-api | Composed cache interface |
SimpleJoinCache | cocache-core | Default JoinCache impl |
KeyFilter | cocache-core | Bloom filter for cache breakdown protection |
BloomKeyFilter | cocache-core | Guava BloomFilter impl |
Build Commands
./gradlew build -x test
./gradlew test
./gradlew :cocache-core:test
./gradlew :cocache-core:test --tests "me.ahoo.cache.proxy.ProxyCacheTest"
./gradlew :cocache-spring-redis:check
./gradlew :cocache-spring-boot-starter:check
./gradlew check
What ships with it: 5 files
34.2 KB alongside SKILL.md
agents/
- openai.yaml203 B
references/
- custom-implementation.md10.1 KB
- join-cache.md6.7 KB
- setup.md8.0 KB
- testing.md9.3 KB