feat: unify cache API for next major release#6
Merged
Conversation
Promote the root module as the only public API surface for the next major version. Direct memoization now uses the same option builder as explicit caches, returns constructors with errors, and shares the root cache engine for TTL, stale, and store behavior. Introduce typed cache keys across Cache, Store, and memory implementations so explicit-key caches and direct memoizers can use workload-appropriate key types without helper packages or a /v2 module. Add direct store wiring, hashing internals, and regression coverage for context, error, and stale-on-error memoization paths. Expand the cache engine with private store fast paths, shared refresh-loop infrastructure, background value loading and mirroring, metrics events, serializer support, chain/local/memory stores, and Redis adapter coverage for hybrid cache usage. Refresh the public documentation and examples for the new major version: getting started, concepts, API reference, recipes, production guidance, performance notes, migration guidance, direct profile caching, stale profile caching, HTTP user caching, configuration snapshots, and Redis-backed hybrid profile caching. Upgrade release hygiene with repository skills, docs-skill synchronization, local pre-commit checks, CI-equivalent verification, patched Go security scanning, golangci-lint, govulncheck, Redis adapter validation, race tests, and benchmark smoke checks.
There was a problem hiding this comment.
Pull request overview
This PR refactors go_memoize for an upcoming major release by consolidating the public API around the root module, unifying direct memoizers and explicit caches on a shared cache engine, and expanding the built-in ecosystem (stores, metrics, serializers, background/loader utilities) plus docs/examples and verification tooling.
Changes:
- Unify direct memoizers and explicit caches behind a shared root cache engine and option builder (
Opts()), with constructors returning errors. - Introduce typed cache keys across
Cache,Store, and built-in stores (memory LRU/single/sharded, chain, local file), plus metrics + serializer abstractions. - Add new docs/examples and CI-equivalent local verification scripts; update CI workflow accordingly.
Reviewed changes
Copilot reviewed 97 out of 99 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| unified_api_test.go | Regression tests for unified root API behavior. |
| tagstore.go | Adds optional tag-invalidation store extension interface. |
| stores/memory/store.go | New generic in-memory LRU store with byte cap and tag delete. |
| stores/memory/store_test.go | Tests for memory LRU, sampling, bytes, tags, concurrency. |
| stores/memory/single.go | Atomic single-entry store for one-value workloads. |
| stores/memory/single_test.go | Tests for SingleStore correctness/concurrency. |
| stores/memory/sharded.go | Sharded LRU store to reduce lock contention for distributed keys. |
| stores/memory/sharded_test.go | Tests for sharding, concurrency, and panic cases. |
| stores/memory/options.go | Options for memory stores (max bytes, sampling, shards). |
| stores/local/store.go | Gob-backed local file store implementation. |
| stores/local/store_test.go | Tests for local file store correctness/persistence. |
| stores/chain/store.go | Multi-tier store that backfills on lower-tier hits. |
| stores/chain/store_test.go | Tests for chain store behavior across tiers. |
| stored.go | Adds Stored[V] entry envelope + freshness/staleness state. |
| store.go | Defines typed Store[K,V] interface for cache engine. |
| serializers/serializers_test.go | Tests for JSON/Gob serializers. |
| serializers/json.go | JSON serializer implementation. |
| serializers/gob.go | Gob serializer implementation. |
| serializers/func.go | Functional serializer adapter. |
| serializer.go | Serializer interface for adapter stores (e.g., Redis). |
| scripts/verify-ci-local.sh | CI-equivalent local verification script. |
| scripts/profile.sh | Benchmark profiling helper script. |
| scripts/pre-commit.sh | Pre-commit verification helper script. |
| scripts/check-docs-skill-sync.sh | Enforces docs/examples ↔ skill-doc sync anchors. |
| options.go | New cache construction defaults/options wiring and lifecycle Stop. |
| options_test.go | Validates option/constructor error cases. |
| metrics/inmem.go | In-memory metrics aggregator (counts + latency percentiles). |
| metrics/inmem_test.go | Tests for in-memory metrics aggregation/reset. |
| metrics.go | Public metrics event model and interface. |
| memoize_test.go | Updates memoize tests to new API + adds stale-on-error regression. |
| memoize_error_test.go | Updates error memoizer tests to new Opts() API. |
| memoize_ctx_test.go | Updates context memoizer tests to new Opts() API. |
| loader/loader.go | Periodic loader that caches latest successful value with readiness gating. |
| loader/loader_test.go | Tests for loader refresh, stale-on-error, stop semantics, callbacks. |
| internal/refreshloop/refreshloop.go | Shared refresh-loop utility for loader/background. |
| internal/hash/hash.go | Internal hashing helpers for comparable key types. |
| internal/hash/hash_test.go | Verifies hashing outputs for compatibility. |
| hashing.go | Updates root hashing package name to memoize. |
| hashing_test.go | Updates hashing tests to memoize package. |
| go.mod | Updates module Go version. |
| examples/README.md | Index for production-shaped example packages. |
| examples/http_user_cache/user_service.go | Example explicit cache service using memory store + stale policies. |
| examples/http_user_cache/user_service_test.go | Tests caching behavior via httptest. |
| examples/http_user_cache/README.md | README for HTTP user cache example. |
| examples/http_user_cache/beeceptor_repository.go | Beeceptor-shaped repository for HTTP user example. |
| examples/direct_stale_profile_cache/README.md | README for direct stale memoizer example. |
| examples/direct_stale_profile_cache/profile_service.go | Service using direct memoizer with stale-while-revalidate + stale-on-error. |
| examples/direct_stale_profile_cache/profile_service_test.go | Tests direct stale memoizer caching via httptest. |
| examples/direct_stale_profile_cache/beeceptor_repository.go | Beeceptor-shaped repo for direct stale profile example. |
| examples/direct_profile_cache/README.md | README for basic direct memoizer example. |
| examples/direct_profile_cache/profile_service.go | Service using direct memoizer with TTL. |
| examples/direct_profile_cache/profile_service_test.go | Tests direct memoizer caching via httptest. |
| examples/direct_profile_cache/beeceptor_repository.go | Beeceptor-shaped repo for direct profile example. |
| examples/config_snapshot/README.md | README for background config snapshot example. |
| examples/config_snapshot/config_service.go | Background snapshot service using background.Keep. |
| examples/config_snapshot/config_service_test.go | Tests snapshot immutability + initial load via httptest. |
| examples/config_snapshot/beeceptor_source.go | Beeceptor-shaped config source for snapshot example. |
| errors.go | Adds shared public errors (missing store, invalid TTL, etc.). |
| docs/PERFORMANCE.md | Architecture/performance notes + benchmark results format. |
| docs/MIGRATION.md | Migration guide to root-module-only API and new patterns. |
| docs/GETTING_STARTED.md | Getting started guide for direct + explicit caches. |
| docs/CONCEPTS.md | Concepts doc (keys, stores, freshness/staleness, shutdown). |
| direct_store.go | Default in-process store for direct memoizers. |
| direct_options.go | Shared options builder and direct-cache constructor. |
| CONTEXT.md | Repository context doc for contributors/agents. |
| clock.go | Clock abstractions + ticker-based clock implementation. |
| cache.go | Replaces legacy cache with shared cache engine (TTL/stale/flight/metrics). |
| cache_fast_path_test.go | Tests for store fast paths + flight waiting behavior. |
| benchmarks/profiling_test.go | Opt-in profiling via BENCH_PROFILE=1. |
| benchmarks/lru_memoize_test.go | Regression tests for LRU benchmark helper wrappers. |
| benchmarks/lru_memoize_helpers_test.go | Benchmark helper functions using typed cache engine and stores. |
| benchmarks/cache_benchmark_test.go | Adds cache/store benchmarks (hot hit, stampede, stale stampede, etc.). |
| benchmarks/benchmark_test.go | Updates direct memoizer benchmarks and adds LRU comparison benches. |
| background/value.go | Atomic background value container. |
| background/options.go | Background keep/mirror options (callbacks, write-through). |
| background/background.go | Keep/Mirror implementations using refreshloop. |
| background/background_test.go | Tests for background keep/mirror behavior, error paths, write-through. |
| AGENTS.md | Documents which skill docs to use for repo work. |
| adapters/redis/store.go | Redis store adapter with serializer + TTL derived from Stored envelope. |
| adapters/redis/store_test.go | Unit tests for redis store configuration/key encoding/TTL helper. |
| adapters/redis/integration_test.go | Optional integration test (requires REDIS_ADDR). |
| adapters/redis/go.sum | Redis adapter module dependency lockfile. |
| adapters/redis/go.mod | Redis adapter as separate module with replace to root. |
| adapters/redis/examples/hybrid_profile_cache/README.md | README for hybrid L1 memory + L2 Redis example. |
| adapters/redis/examples/hybrid_profile_cache/profile_service.go | Example service wiring memory+redis via chain store and direct memoizer. |
| adapters/redis/examples/hybrid_profile_cache/profile_service_test.go | Tests hybrid behavior with memory-backed tiers. |
| adapters/redis/examples/hybrid_profile_cache/beeceptor_repository.go | Beeceptor-shaped repo for hybrid example. |
| .gitignore | Updates ignore patterns (adds .opencode, docs/superpowers). |
| .github/workflows/ci.yml | CI now runs full verification script with explicit tool installs. |
| .githooks/pre-commit | Git hook shim to run scripts/pre-commit.sh. |
| .agents/skills/go-performance-optimization/SKILL.md | Adds performance optimization guidance/verification steps. |
| .agents/skills/go-memoize-package/SKILL.md | Updates skill doc with new API rules, semantics, verification, gotchas. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Validate explicit cache construction earlier by returning ErrMissingStore when New is called without a store outside bypass mode, and reject typed-nil stores passed through WithStore. Make background Value.Get safe for zero-value use, and make the shared refresh loop ignore non-positive intervals instead of panicking from time.NewTicker. Tighten review-driven tests by passing OnRefresh into Mirror cancellation coverage and deriving byte-capacity test limits from runtime entry size instead of hard-coded architecture assumptions.
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.
Promote the root module as the only public API surface for the next major version. Direct memoization now uses the same option builder as explicit caches, returns constructors with errors, and shares the root cache engine for TTL, stale, and store behavior.
Introduce typed cache keys across Cache, Store, and memory implementations so explicit-key caches and direct memoizers can use workload-appropriate key types. Add direct store wiring, hashing internals, and regression coverage for context, error, and stale-on-error memoization paths.
Expand the cache engine with private store fast paths, shared refresh-loop infrastructure, background value loading and mirroring, metrics events, serializer support, chain/local/memory stores, and Redis adapter coverage for hybrid cache usage.
Refresh the public documentation and examples for the new major version: getting started, concepts, API reference, recipes, production guidance, performance notes, migration guidance, direct profile caching, stale profile caching, HTTP user caching, configuration snapshots, and Redis-backed hybrid profile caching.
Upgrade release hygiene with repository skills, docs-skill synchronization, local pre-commit checks, CI-equivalent verification, patched Go security scanning, golangci-lint, govulncheck, Redis adapter validation, race tests, and benchmark smoke checks.