Skip to content

yikakia/cachalot

Repository files navigation

cachalot

A universal cache facade library for Go, supporting both out-of-the-box usage and deep customization.

MIT license CI Go.Dev reference Ask DeepWiki

📘 中文文档请查看: README_zh.md

Project Positioning

cachalot is a generic cache library based on Go generics. The core goal is to reduce the combinatorial complexity of m cache implementations with n cache usage patterns from O(m*n) to O(m+n). It is not a specific cache system, but rather abstracts common caching patterns into reusable and composable capabilities.

Project Status

This project is currently focused on gathering early feedback and is not production-ready yet. The API is not frozen, and APIs/default behaviors may still change before the first stable release. Feedback is highly welcome on:

  • API naming and semantics.
  • Usage ergonomics in real service flows.
  • Default strategy implementations (fetch/write-back/singleflight).
  • Extension experience for custom store/factory/decorator integrations.

Comparison with eko/gocache

Both cachalot and eko/gocache aim to simplify cache access, but they optimize for different things:

  • eko/gocache focuses on a unified facade with ready-to-use adapters for fast adoption.
  • cachalot focuses on structured layering with explicit Store, Factory, and Decorator boundaries.

This separation makes it easier to compose features by evolving storage implementation, construction/type-bridging logic, and usage policies independently.

Features

  • Single-level cache with pluggable Store implementations.
  • Multi-level cache with customizable fetch and write-back policies.
  • Decorator-based capability orchestration (codec, compression, logical expiry, singleflight, miss loader).
  • Unified observability (metrics + logger).
  • Both high-level Builder API (out-of-the-box usage) and low-level core API (fine-grained orchestration).

Install

go get github.com/yikakia/cachalot

Quick Start (Single Cache)

builder, err := cachalot.NewBuilder[User]("user-cache", store)
if err != nil {
	panic(err)
}

cache, err := builder.
	WithCacheMissLoader(loadUser).
	WithCacheMissDefaultWriteBackTTL(time.Minute).
	Build()
if err != nil {
	panic(err)
}

u, err := cache.Get(context.Background(), "user-1")

Running Examples

For complete runnable examples, see examples:

Choosing the Right API

  • Builder API (recommended for most scenarios): Out-of-the-box, with commonly-used features integrated by default.
  • core package (advanced customization): Use when you need precise control over factories, decorator chains, and multi-level policies.

Builder API (Regular Usage)

Single-cache Builder: NewBuilder

Common options:

  • WithCacheMissLoader: Load from origin when a key is missed.
  • WithCacheMissDefaultWriteBackTTL: Default write-back TTL after loader returns successfully.
  • WithSingleflight: Merge concurrent requests.
  • WithCodec: Codec for byte-oriented stores.
  • WithCompression: Byte-stage compression/decompression.
  • WithLogicExpire*: Logical expiration (stale-while-revalidate).
  • WithLogger / WithMetrics: Observability integration.

Multi-cache Builder: NewMultiBuilder

Common options:

  • WithLoader: Fallback loader when all levels miss (singleflight for the same key is enabled by default; disable via WithSingleflight(false)).
  • WithFetchPolicy: Customize probing order and load strategy across levels.
  • WithWriteBack / WithWriteBackFilter: Control write-back behavior and target-level filtering rules.
  • WithErrorHandling: Control strict/tolerant behavior for write-back failures.

core (Advanced Orchestration)

For full control over the pipeline, use:

  • core/cache: Single-cache abstractions (Cache, Store, Option, Factory/Decorator).
  • core/multicache: Multi-level cache orchestration (Config, policy functions, error handling).
  • core/decorator: Reusable capability decorators.

Architecture

The single-cache core architecture is divided into three layers:

  • Decorator: Defines "how to use cache" (concurrent deduplication, load-through, cache penetration protection, observability, etc.).
  • Factory: Adapts Store to Cache[T] and handles type bridging.
  • Store: Encapsulates the concrete storage client and provides unified read/write semantics.

The default assembly order of Builder and the decorator execution model are described in:

Documentation Navigation

Testing and Mocks

This repo uses mockgen to generate interface mocks for unit tests:

  • internal/mocks/mock_cache.go for cache.Cache[T]
  • internal/mocks/mock_store.go for cache.Store

Regenerate mocks with:

go generate ./internal/mocks

Run tests:

go test ./...

Or run the full script (including submodules):

./run_tests.sh

License

© yikakia, 2026~time.Now()

Released under the MIT License.

About

The cache facade for Golang, aims to be developer friendly

Resources

License

Contributing

Stars

Watchers

Forks

Contributors