cachalot

package module
v0.0.0-...-ba4e952 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 4, 2026 License: MIT Imports: 13 Imported by: 2

README

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.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Builder

type Builder[T any] struct {
	// contains filtered or unexported fields
}

func NewBuilder

func NewBuilder[T any](name string, store cache.Store, opts ...cache.Option[T]) (*Builder[T], error)

func (*Builder[T]) Build

func (b *Builder[T]) Build() (cache.Cache[T], error)

func (*Builder[T]) WithByteTransforms

func (b *Builder[T]) WithByteTransforms(ts ...ByteTransform) *Builder[T]

WithByteTransforms 追加字节级转换链(按声明顺序执行)。

func (*Builder[T]) WithCacheMissDefaultWriteBackTTL

func (b *Builder[T]) WithCacheMissDefaultWriteBackTTL(d time.Duration) *Builder[T]

如果不调用 WithCacheMissLoader 传入回源函数的话 此设置无效

func (*Builder[T]) WithCacheMissLoader

func (b *Builder[T]) WithCacheMissLoader(fn decorator.LoaderFn[T]) *Builder[T]

func (*Builder[T]) WithCodec

func (b *Builder[T]) WithCodec(codec codec.Codec) *Builder[T]

开启 Codec 功能

func (*Builder[T]) WithCompression

func (b *Builder[T]) WithCompression(c Compression) *Builder[T]

WithCompression 以 Decorator 风格声明压缩能力,但内部会编译到 byte-stage。

func (*Builder[T]) WithDecorators

func (b *Builder[T]) WithDecorators(decorators ...cache.Decorator[T]) *Builder[T]

WithDecorators 如果用 WithOptions 也传入了装饰器,则 WithOptions 传入的更靠外层

func (*Builder[T]) WithFactory

func (b *Builder[T]) WithFactory(factory cache.CacheFactory[T]) *Builder[T]

WithFactory 显式声明使用自定义装配计划,与 staged features 互斥。

func (*Builder[T]) WithLogger

func (b *Builder[T]) WithLogger(logger telemetry.Logger) *Builder[T]

func (*Builder[T]) WithLogicExpireBytesAdapter

func (b *Builder[T]) WithLogicExpireBytesAdapter(enable bool) *Builder[T]

如果 T = []byte,是否启用内置的 LogicTTLBytesAdapter 适配器

启用后会在逻辑过期功能的基础上,自动将 LogicTTLValue[[]byte] 编码为 []byte 存储,格式为 [8-byte little-endian UnixNano expireAt][raw payload] 使用场景: 源数据是 []byte 使用了压缩功能,同时还想使用逻辑过期的功能,可以启用这个适配器,避免引入 codec 包和额外的编码开销。

func (*Builder[T]) WithLogicExpireDefaultLogicTTL

func (b *Builder[T]) WithLogicExpireDefaultLogicTTL(d time.Duration) *Builder[T]

默认设置的逻辑过期时间 需要大于等于0

func (*Builder[T]) WithLogicExpireDefaultWriteBackTTL

func (b *Builder[T]) WithLogicExpireDefaultWriteBackTTL(d time.Duration) *Builder[T]

逻辑过期回源后,回写时的物理过期时间 需要大于等于0

func (*Builder[T]) WithLogicExpireEnabled

func (b *Builder[T]) WithLogicExpireEnabled(enabled bool) *Builder[T]

开启逻辑过期功能

func (*Builder[T]) WithLogicExpireLoader

func (b *Builder[T]) WithLogicExpireLoader(fn decorator.LoaderFn[T]) *Builder[T]

func (*Builder[T]) WithMetrics

func (b *Builder[T]) WithMetrics(metrics telemetry.Metrics) *Builder[T]

func (*Builder[T]) WithNilCacheFn

func (b *Builder[T]) WithNilCacheFn(fn decorator.ProtectionFn[T]) *Builder[T]

WithNilCacheFn 启用防缓存击穿功能

func (*Builder[T]) WithNilCacheWriteBackTTL

func (b *Builder[T]) WithNilCacheWriteBackTTL(ttl time.Duration) *Builder[T]

func (*Builder[T]) WithObserveDecorator

func (b *Builder[T]) WithObserveDecorator(d cache.Decorator[T]) *Builder[T]

WithObserveDecorator 自定义最外层进行观测的 observer 装饰层

func (*Builder[T]) WithOptions

func (b *Builder[T]) WithOptions(opts ...cache.Option[T]) *Builder[T]

WithOptions 自定义的可选项,优先级最高

如果传入 cache.WithFactory 则会覆盖 Builder 的装配计划 如果传入 cache.WithObservable 则会覆盖 WithLogger 和 WithMetrics 的特性开启 如果传入 cache.WithDecorator 则会在 WithDecorators 的外层,观测层的内层

func (*Builder[T]) WithSingleflight

func (b *Builder[T]) WithSingleflight(enable bool) *Builder[T]

给 Get GetWithTTL 开启 singleflight 功能

func (*Builder[T]) WithTypeAdapter

func (b *Builder[T]) WithTypeAdapter(a TypeAdapter[T]) *Builder[T]

WithTypeAdapter 覆盖默认类型适配器。

type ByteTransform

type ByteTransform func(next cache.Cache[[]byte], ob *telemetry.Observable) (cache.Cache[[]byte], error)

ByteTransform 用于构建 []byte 层能力链(压缩/加密/签名等)。

type Compression

type Compression interface {
	Compress(src []byte) ([]byte, error)
	Decompress(src []byte) ([]byte, error)
}

Compression 定义字节压缩与解压能力。

type MultiBuilder

type MultiBuilder[T any] struct {
	// contains filtered or unexported fields
}

MultiBuilder 用于构建 MultiCache

func NewMultiBuilder

func NewMultiBuilder[T any](name string, caches ...cache.Cache[T]) *MultiBuilder[T]

NewMultiBuilder 创建一个新的 MultiBuilder caches 是多级缓存的列表,优先级从前到后 默认配置时 需要使用 MultiBuilder.WithLoader 提供回源函数

默认配置为

FetchPolicy = multicache.FetchPolicySequential 顺序遍历 cache 获取,source 兜底 需要调用 MultiBuilder.WithLoader 提供回源函数 WriteBackCacheFilter = multicache.MissedCacheFilter 仅回源返回 cache.ErrNotFound 的 cache WriteBackFn = multicache.WriteBackParallel[T](time.Minute) 并行写回,同步等待,写回的ttl为一分钟 ErrorHandleMode = multicache.ErrorHandleTolerant 宽容模式 当 WriteBackFn 返回 err 时,仅记录日志

func (*MultiBuilder[T]) Build

func (b *MultiBuilder[T]) Build() (multicache.MultiCache[T], error)

Build 构建 MultiCache

func (*MultiBuilder[T]) WithErrorHandling

func (b *MultiBuilder[T]) WithErrorHandling(mode multicache.ErrorHandleMode) *MultiBuilder[T]

WithErrorHandling 设置错误处理模式

func (*MultiBuilder[T]) WithFetchPolicy

func (b *MultiBuilder[T]) WithFetchPolicy(policy multicache.FetchPolicy[T]) *MultiBuilder[T]

WithFetchPolicy 设置查询策略

func (*MultiBuilder[T]) WithLoader

func (b *MultiBuilder[T]) WithLoader(fn decorator.LoaderFn[T]) *MultiBuilder[T]

WithLoader 设置回源函数 默认配置 FetchPolicy = multicache.FetchPolicySequential 时必传 不然会运行时 panic

func (*MultiBuilder[T]) WithLogger

func (b *MultiBuilder[T]) WithLogger(logger telemetry.Logger) *MultiBuilder[T]

func (*MultiBuilder[T]) WithMetrics

func (b *MultiBuilder[T]) WithMetrics(metrics telemetry.Metrics) *MultiBuilder[T]

func (*MultiBuilder[T]) WithRequiredLoader

func (b *MultiBuilder[T]) WithRequiredLoader(enabled bool) *MultiBuilder[T]

WithRequiredLoader 设置是否必须提供 LoaderFn。 当策略不依赖 LoaderFn 时可设置为 false。

func (*MultiBuilder[T]) WithSingleflight

func (b *MultiBuilder[T]) WithSingleflight(enabled bool) *MultiBuilder[T]

WithSingleflight LoaderFn 的 singleflight 封装 默认开启

func (*MultiBuilder[T]) WithWriteBack

func (b *MultiBuilder[T]) WithWriteBack(fn multicache.WriteBackFn[T]) *MultiBuilder[T]

WithWriteBack 设置回写策略

func (*MultiBuilder[T]) WithWriteBackFilter

func (b *MultiBuilder[T]) WithWriteBackFilter(filter multicache.WriteBackCacheFilter[T]) *MultiBuilder[T]

WithWriteBackFilter 设置回写过滤策略

type TypeAdapter

type TypeAdapter[T any] func(next cache.Cache[[]byte], ob *telemetry.Observable) (cache.Cache[T], error)

TypeAdapter 负责 T <-> []byte 的类型转换。

Directories

Path Synopsis
core
mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
stores
redis module
ristretto module
valkey module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL