Documentation
¶
Overview ¶
Package entitycache 提供通用实体缓存抽象。
EntityCache[K, V] 是 K→V 的缓存接口,由两种实现提供服务:
- FullCache:永远写入,等价于现有 SyncMap 行为(用于 admin 维护的小规模实体)
- LRUCache:基于 hashicorp/golang-lru,按容量淘汰,支持 miss 时 RPC 拉取、 负缓存与 apply-if-present 推送语义(用于高基数实体如 token / user)
抽象层不知道任何业务概念。Token 双键索引、关联实体 warm 等组合 行为由 cache.Store 包内的派生层负责。
Index ¶
- Variables
- type Action
- type Config
- type EntityCache
- type FullCache
- func (c *FullCache[K, V]) Apply(action Action, key K, value V)
- func (c *FullCache[K, V]) Clear()
- func (c *FullCache[K, V]) Delete(key K)
- func (c *FullCache[K, V]) Get(_ context.Context, key K) (V, bool, error)
- func (c *FullCache[K, V]) Len() int
- func (c *FullCache[K, V]) Peek(key K) (V, bool)
- func (c *FullCache[K, V]) Range(fn func(K, V) bool)
- func (c *FullCache[K, V]) Set(key K, value V)
- func (c *FullCache[K, V]) Stats() Stats
- type LRUCache
- func (c *LRUCache[K, V]) Apply(action Action, key K, value V)
- func (c *LRUCache[K, V]) Clear()
- func (c *LRUCache[K, V]) Delete(key K)
- func (c *LRUCache[K, V]) Get(ctx context.Context, key K) (V, bool, error)
- func (c *LRUCache[K, V]) Len() int
- func (c *LRUCache[K, V]) MutationEpoch() uint64
- func (c *LRUCache[K, V]) Peek(key K) (V, bool)
- func (c *LRUCache[K, V]) Range(fn func(K, V) bool)
- func (c *LRUCache[K, V]) Set(key K, value V)
- func (c *LRUCache[K, V]) SetIfMutationEpoch(epoch uint64, key K, value V) bool
- func (c *LRUCache[K, V]) Stats() Stats
- type Lifecycle
- func (l *Lifecycle) Close()
- func (l *Lifecycle) Context() context.Context
- func (l *Lifecycle) Done() <-chan struct{}
- func (l *Lifecycle) Go(run func(context.Context)) bool
- func (l *Lifecycle) GoLoad(run func(context.Context)) bool
- func (l *Lifecycle) GoRefresh(run func(context.Context)) bool
- func (l *Lifecycle) ResourceCounts() (loads, refreshes int64)
- type Loader
- type LoaderFunc
- type MutationEpochCache
- type RefreshConfig
- type RefreshOutcome
- type Refresher
- type Stats
Constants ¶
This section is empty.
Variables ¶
var ErrLoadInvalidated = errors.New("entitycache: load invalidated")
ErrLoadInvalidated means a key was invalidated while its cold load was in flight. Callers must retry instead of using the stale loader result.
var ErrLoadLimitReached = errors.New("entitycache: concurrent load limit reached")
ErrLoadLimitReached 表示已有过多不同 key 正在加载;同 key follower 不受影响。
var ErrNotFound = errors.New("entity not found")
ErrNotFound 表示 Loader 已确认 key 在源端不存在。 LRUCache 据此触发负缓存。
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config[K comparable, V any] struct { // Capacity 是最大条目数(必须 > 0)。 Capacity int // MaxConcurrentLoads 限制同时冷加载的不同 key 数。0 使用有界默认值;负值非法。 MaxConcurrentLoads int // Loader 在 Get miss 时被调用。可为 nil(仅本地缓存)。 Loader Loader[K, V] // NegativeTTL 是负缓存("key 不存在")的过期时间。0 表示禁用负缓存。 NegativeTTL time.Duration // Now 用于测试控制时间。零值时使用 time.Now。 Now func() time.Time // OnEvict 在 LRU 因容量淘汰一条**正常**条目时被调用(负缓存条目不触发)。 // 用于派生反向索引同步清理(如 tokenStore.byID)。可为 nil。 OnEvict func(key K, value V) // Refresh 提供缓存韧性参数(动态读取,支持运行时改值)。 // 非 nil 且 Loader 非 nil 时启用 stale-while-revalidate + detached 冷 miss。 // nil 时退化为原行为(冷 miss 沿用调用方 ctx,不做后台刷新)。 Refresh func() RefreshConfig Lifecycle *Lifecycle }
Config 是 LRUCache 的构造参数。
type EntityCache ¶
type EntityCache[K comparable, V any] interface { // Get 命中返回 (v, true, nil);未命中且未配置 Loader 返回 (zero, false, nil); // 已配置 Loader 时同步触发拉取。Loader 返回 ErrNotFound 走负缓存 // 后续返回 (zero, false, ErrNotFound);其他错误透传。 Get(ctx context.Context, key K) (V, bool, error) // Peek 仅查本地,不触发 Loader。 Peek(key K) (V, bool) // Apply 处理 push 事件。 // FullCache 永远写入或删除;LRUCache 仅当 key 已在缓存时操作。 Apply(action Action, key K, value V) // Set 直接写入,不经 apply-if-present 检查(用于 FullSync 等主动加载场景)。 Set(key K, value V) // Delete 直接删除。 Delete(key K) // Clear 删除所有正向、负向和可见缓存状态。 Clear() // Len 返回当前条目数。 Len() int // Range 遍历当前所有条目。回调返回 false 终止遍历。 Range(func(K, V) bool) // Stats 返回运行计数快照。 Stats() Stats }
EntityCache 是通用实体缓存接口。
type FullCache ¶
type FullCache[K comparable, V any] struct { // contains filtered or unexported fields }
FullCache 永远写入,等价于现有 SyncMap 行为。无 LRU 淘汰、无 Loader。
func NewFullCache ¶
func NewFullCache[K comparable, V any]() *FullCache[K, V]
NewFullCache 创建一个空的 FullCache。
type LRUCache ¶
type LRUCache[K comparable, V any] struct { // contains filtered or unexported fields }
LRUCache 基于 hashicorp/golang-lru,带 Loader、负缓存、metrics。
func NewLRUCache ¶
func NewLRUCache[K comparable, V any](cfg Config[K, V]) (*LRUCache[K, V], error)
NewLRUCache 构造 LRUCache。Capacity <= 0 返回错误(fail-fast)。
func (*LRUCache[K, V]) Apply ¶
Apply:apply-if-present。LRU 仅当 key 存在时写入或删除。
已知非原子窗口:ActionSet 的 Contains→store(Add) 之间若有并发 Delete, 这次 re-add 会复活已删条目(resurrection)。这是被接受的——写入幂等,SWR 刷新本就罕见,且 hashicorp/lru 不提供原子的 update-if-present。不加锁。
func (*LRUCache[K, V]) Clear ¶ added in v0.0.16
func (c *LRUCache[K, V]) Clear()
Clear purges positive and negative entries and invalidates every active cold load. Only active-flight generations are retained, so bookkeeping is bounded by MaxConcurrentLoads and is removed when each flight completes.
func (*LRUCache[K, V]) Get ¶
Get 命中返回 (v, true, nil)。 miss 且配置了 Loader 时通过 singleflight 单飞调用,结果写入缓存。 Loader 返回 ErrNotFound 时进入负缓存(如启用),返回 (zero, false, ErrNotFound)。 Loader 返回其他错误透传不缓存。
func (*LRUCache[K, V]) MutationEpoch ¶ added in v0.0.16
func (*LRUCache[K, V]) SetIfMutationEpoch ¶ added in v0.0.16
type Lifecycle ¶ added in v0.0.13
type Lifecycle struct {
// contains filtered or unexported fields
}
func NewLifecycle ¶ added in v0.0.13
func NewLifecycle() *Lifecycle
func (*Lifecycle) ResourceCounts ¶ added in v0.0.13
type Loader ¶
type Loader[K comparable, V any] interface { Load(ctx context.Context, key K) (V, error) }
Loader 封装一次 miss 时的远端拉取。 返回 ErrNotFound 时缓存写入负条目;其他错误透传不缓存。
type LoaderFunc ¶
type LoaderFunc[K comparable, V any] func(context.Context, K) (V, error)
LoaderFunc 适配普通函数到 Loader 接口。
type MutationEpochCache ¶ added in v0.0.16
type MutationEpochCache[K comparable, V any] interface { MutationEpoch() uint64 SetIfMutationEpoch(epoch uint64, key K, value V) bool }
MutationEpochCache lets side loaders conditionally warm a cache only when no invalidation happened after the remote request began.
type RefreshConfig ¶ added in v0.0.8
type RefreshConfig struct {
LoadTimeout time.Duration // 冷 miss 阻塞加载超时(detached)
RefreshAfter time.Duration // 条目多旧触发后台刷新;<=0 禁用 soft-TTL
RefreshTimeout time.Duration // 单次后台刷新尝试超时
RefreshMaxRetries int // 单次触发内 failsafe 重试次数
RefreshBackoffBase time.Duration
RefreshBackoffMax time.Duration
}
RefreshConfig 是缓存韧性参数快照,由调用方通过 Config.Refresh 动态提供 (通常映射自管理后台 Settings,支持运行时改值即时生效)。
type RefreshOutcome ¶ added in v0.0.8
type RefreshOutcome int
RefreshOutcome 是一次后台刷新的三态结果。
const ( // RefreshOK 成功拿到新值。 RefreshOK RefreshOutcome = iota // RefreshGone 源端明确返回 ErrNotFound(可达且已删/吊销)→ 应逐出。 RefreshGone RefreshUnavailable )
type Refresher ¶ added in v0.0.8
type Refresher[K comparable, V any] struct { // contains filtered or unexported fields }
Refresher 在后台韧性地把 key 拉回来,不持有任何缓存引用——只通过 handler 回调结果。 同 key 同时只有一次刷新在跑(去重)。失败带 failsafe 退避重试;ErrNotFound 不重试。
func NewRefresher ¶ added in v0.0.8
func NewRefresher[K comparable, V any](load Loader[K, V], cfg func() RefreshConfig) *Refresher[K, V]
NewRefresher 构造。load 与 cfg 必须非 nil。
func NewRefresherWithLifecycle ¶ added in v0.0.13
func NewRefresherWithLifecycle[K comparable, V any](load Loader[K, V], cfg func() RefreshConfig, lifecycle *Lifecycle) *Refresher[K, V]
func (*Refresher[K, V]) TriggerRefresh ¶ added in v0.0.8
func (r *Refresher[K, V]) TriggerRefresh(key K, handler func(RefreshOutcome, V))
TriggerRefresh 异步触发一次刷新;同 key 已在刷新则直接返回(去重),不重复打远端。 完成后回调 (outcome, value):RefreshOK 时 value 为新值,否则为零值。 in-flight 标记一直持有到 handler 回调返回:同 key 的并发触发在整个 load + handler 期间被丢弃(去重窗口覆盖全程,设计如此)。