Exposed Cache Foundation
Latest stable Based on Exposed release 1.11.0
bluetape4k-exposed-cache defines the repository contracts and configuration shared by the Caffeine, Lettuce, and Redisson adapters. It does not create a cache client or choose a backend for the application.
Problem
Section titled “Problem”A cache-backed repository has two state owners: the cache and the database. The application must decide how misses are loaded, when writes become durable, what invalidation removes, and who closes backend resources. This module gives every adapter the same vocabulary for those decisions.
When to use it
Section titled “When to use it”Use it when implementing a cache adapter or writing code against the common JdbcCacheRepository, SuspendedJdbcCacheRepository, or R2dbcCacheRepository contract. Most applications should depend on one concrete backend module instead; it already brings this foundation transitively.
Coordinates
Section titled “Coordinates”Import the ecosystem BOM once, then omit the library version:
dependencies { implementation(platform("io.github.bluetape4k:bluetape4k-dependencies:<version>")) implementation("io.github.bluetape4k.exposed:bluetape4k-exposed-cache")}Core concepts
Section titled “Core concepts”| Decision | Values | Operational meaning |
|---|---|---|
| Location | LOCAL, REMOTE, NEAR_CACHE | One JVM, Redis, or local front cache plus Redis |
| Write policy | READ_ONLY, WRITE_THROUGH, WRITE_BEHIND | Cache-only put, synchronous database write, or deferred database write |
| Read-through | get/getAll | A miss loads from the database and populates the cache |
| Invalidation | invalidate, invalidateAll, clear | Removes cache state; the common contract does not delete database rows |
An ordinary put is not automatically write-through. Its durability depends on the repository’s cacheWriteMode and concrete writer configuration.
Quick start
Section titled “Quick start”val entity = repository.get(id) // cache miss -> DB load -> cache fillrepository.invalidate(id) // cache only; DB row remainsrepository.close() // release queues/connections owned by the adapterStart by choosing the concrete backend in the cache selection guide, then implement the table mapping in that backend’s abstract repository.
API by task
Section titled “API by task”| Task | API |
|---|---|
| Bypass cache | findByIdFromDb, findAllFromDb, countFromDb |
| Read through cache | containsKey, get, getAll |
| Write according to policy | put, putAll |
| Evict cached state | invalidate, invalidateAll, clear |
| Release resources | close |
JDBC has blocking and suspend contracts. R2DBC exposes suspend operations throughout, including row-to-entity conversion.
Recommended patterns
Section titled “Recommended patterns”Keep transaction-owned database updates explicit when cache and database cannot commit atomically. For cache-aside, commit the database change first and invalidate the affected key. Use true write-through only when the adapter owns a configured map writer. Use write-behind only for data that tolerates delayed persistence and a bounded failure window.
Namespace keys with a stable keyPrefix or cache name. Treat the serialized key and value format as stored-data contracts: changing them without a migration leaves unreadable or duplicate entries behind.
Integrations
Section titled “Integrations”- Caffeine: in-process
LOCALcache for JDBC or R2DBC. - Lettuce: Redis-backed repository with an explicit value codec; selected suspend paths can add a Caffeine near cache.
- Redisson: Redis
RMap/RLocalCachedMapwith loader and writer integration. - Test fixtures: reusable read-through, write-through, write-behind, and invalidation scenarios.
Configuration
Section titled “Configuration”LocalCacheConfig defaults to 10,000 entries, ten-minute expiry after write, and READ_ONLY. Its key prefix must be nonblank; sizes and durations must be positive; the write-behind queue must hold at least one batch. Redis adapters add backend configuration and may enable retry, timeout, and circuit-breaking through RedisRepositoryResilienceConfig.
Failure modes
Section titled “Failure modes”- A local cache is not shared across application instances, so invalidation can diverge.
- Redis failure can turn a cache into an availability dependency unless fallback and timeout policy are explicit.
- Write-behind can lose accepted-but-unflushed data during process failure.
- A codec or key-format change can strand existing Redis entries.
- Calling
closetoo late or not at all can leave a queue, connection, or coroutine scope alive.
Operations
Section titled “Operations”Observe cache hit/miss behavior, backend latency, retry/circuit state, write-behind queue depth, rejected writes, and drain results. Set TTL from the data’s staleness budget, not from a generic cache default. Document whether a Redis outage fails the request, bypasses cache, or serves stale local data.
Testing
Section titled “Testing”Use the module’s test fixtures to lock down miss loading, partial getAll misses, synchronous durability, deferred flush, and cache-only invalidation. Give each test a unique key prefix/cache name, clear it in teardown, and close repositories and application-owned clients. Run distributed adapters against an isolated Redis instance rather than sharing developer data.
Workshops and learning path
Section titled “Workshops and learning path”- Read the cache selection guide to choose local, remote, or near cache.
- Implement the smallest repository with the matching Caffeine, Lettuce, or Redisson module.
- Add failure tests before enabling write-behind or near cache.
- Continue with exposed-workshop for end-to-end cache repository examples.
Limitations
Section titled “Limitations”The contracts do not provide a distributed transaction between cache and database, choose a serialization format, provision Redis, or make a local cache coherent across JVMs. Backend-specific semantics take precedence where their writer or invalidation configuration is more precise.
Release diagrams
Section titled “Release diagrams”These diagrams are loaded directly from README assets published with the 1.11.0 release and pinned to its immutable commit. They describe this manual’s released structure and runtime flows, not later Snapshot changes. Select a preview to open the SVG at the same release commit.
Repository Interface Class Diagram
Section titled “Repository Interface Class Diagram”Release README: exposed/cache/README.md
Cache Configuration Decision Map
Section titled “Cache Configuration Decision Map”Release README: exposed/cache/README.md
Write Strategy Patterns diagram
Section titled “Write Strategy Patterns diagram”Release README: exposed/cache/README.md


