Documentation
¶
Index ¶
- Variables
- func AutoInitKeyBuilder(opts ...KeyBuilderOption)
- func Decr(ctx context.Context, key string) (int64, error)
- func DeleteWithPrefix(ctx context.Context, key string, prefix string) error
- func Exists(ctx context.Context, key string) (bool, error)
- func ExtendLock(ctx context.Context, token *LockToken, ttl time.Duration) error
- func ForceUnlock(ctx context.Context, key string) error
- func Get(ctx context.Context, key string, dest any) (bool, error)
- func GetLockTTL(ctx context.Context, key string) (time.Duration, error)
- func GetRaw(ctx context.Context, key string) (string, error)
- func GetTTL(ctx context.Context, key string) (time.Duration, error)
- func GetWithPrefix(ctx context.Context, key string, dest any, prefix string) (bool, error)
- func Incr(ctx context.Context, key string) (int64, error)
- func IncrBy(ctx context.Context, key string, value int64) (int64, error)
- func Init()
- func InitKeyBuilder(prefix string, opts ...KeyBuilderOption)
- func IsLocked(ctx context.Context, key string) (bool, error)
- func K(key string) string
- func KCounter(key string) string
- func KLock(key string) string
- func KPerm(key string) string
- func KSession(key string) string
- func KTemp(key string) string
- func Lock(ctx context.Context, key string, ttl time.Duration) (bool, error)
- func LockWithPrefix(ctx context.Context, key string, ttl time.Duration, prefix string) (bool, error)
- func SetDefaultCacheManager(m *CacheManager)
- func SetExpire(ctx context.Context, key string, ttl time.Duration) (bool, error)
- func SetRaw(ctx context.Context, key string, value string, ttl time.Duration) error
- func SetWithPrefix(ctx context.Context, key string, value any, ttl time.Duration, prefix string) error
- func Unlock(ctx context.Context, token *LockToken) error
- func UnlockByKey(ctx context.Context, key string) error
- func UnlockWithPrefix(ctx context.Context, key string, prefix string) error
- func WithLock(ctx context.Context, key string, ttl time.Duration, ...) error
- func WithLockAutoExtend(ctx context.Context, key string, initialTTL time.Duration, ...) error
- type CacheManager
- type CacheService
- type KeyBuilder
- func (kb *KeyBuilder) Build(key string) string
- func (kb *KeyBuilder) BuildCounter(key string) string
- func (kb *KeyBuilder) BuildLock(key string) string
- func (kb *KeyBuilder) BuildPattern(pattern string) string
- func (kb *KeyBuilder) BuildPerm(key string) string
- func (kb *KeyBuilder) BuildSession(key string) string
- func (kb *KeyBuilder) BuildTemp(key string) string
- func (kb *KeyBuilder) GetPrefix() string
- func (kb *KeyBuilder) SetPrefix(prefix string) *KeyBuilder
- type KeyBuilderOption
- type LockToken
Constants ¶
This section is empty.
Variables ¶
var ( ErrLockNotHeld = errors.New("锁未被当前客户端持有") ErrLockExpired = errors.New("锁已过期") ErrRedisNotReady = errors.New("Redis 未初始化") // ErrLockNotAcquired 表示锁被其它客户端持有,业务函数未执行。 ErrLockNotAcquired = errors.New("未获取到锁") // ErrInvalidLockTTL 表示锁 TTL 小于 Redis PX 支持的 1ms 粒度或非正。 ErrInvalidLockTTL = errors.New("锁 TTL 必须大于等于 1ms") // ErrInvalidLockRetryInterval 表示重试或续期间隔非法。 ErrInvalidLockRetryInterval = errors.New("锁重试/续期间隔必须大于 0") // ErrLockUnexpectedResult Lua 脚本返回了非预期的结果类型(C1b:裸类型断言防护)。 ErrLockUnexpectedResult = errors.New("锁脚本返回非预期结果") // ErrLockFuncNil 表示分布式锁业务函数为空。 ErrLockFuncNil = errors.New("锁业务函数不能为空") )
分布式锁错误
Functions ¶
func AutoInitKeyBuilder ¶
func AutoInitKeyBuilder(opts ...KeyBuilderOption)
AutoInitKeyBuilder 自动从配置初始化键名构建器 配置示例:
app: site_name: "site_a" env: "prod"
func DeleteWithPrefix ¶
DeleteWithPrefix 带前缀的缓存删除
func ExtendLock ¶
ExtendLock 续期锁 参数: token 锁令牌,ttl 新的过期时间
func ForceUnlock ¶
ForceUnlock 强制释放锁(危险操作,仅用于管理场景) 注意: 此函数不检查 Token,强制删除锁
M-E 修复:Redis 未初始化时返回 ErrRedisNotReady 而非 nil——原 nil 让调用方误以为 已解锁成功、实则从未操作。管理脚本应据此重试或告警,而非假设成功。
func Get ¶ added in v1.3.0
Get 获取全局缓存值。命中返回 (true, nil);未命中返回 (false, nil); 缓存未初始化或 Redis 错误返回 (false, err)。
func GetLockTTL ¶
GetLockTTL 获取锁的剩余过期时间。
M-E 修复:Redis 未初始化时返回 (0, ErrRedisNotReady) 而非 (0, nil),调用方可区分 "Redis 不可用"与"锁不存在/已过期"(后者 TTL=-1/-2)。
func GetWithPrefix ¶
GetWithPrefix 带前缀的缓存获取。命中返回 (true, nil);未命中返回 (false, nil); Redis 错误或反序列化失败返回 (false, err)。
func InitKeyBuilder ¶
func InitKeyBuilder(prefix string, opts ...KeyBuilderOption)
InitKeyBuilder 初始化全局键名构建器 参数: prefix 站点别名,如果为空则自动从配置读取 示例:
InitKeyBuilder("site_a") // 手动指定
InitKeyBuilder("") // 自动从配置读取
InitKeyBuilder("", WithSeparator(":")) // 自动读取 + 自定义分隔符
func IsLocked ¶
IsLocked 检查锁是否被占用(不获取锁)。
M-E 修复(失败语义统一):Redis 未初始化时返回 (false, ErrRedisNotReady) 而非 (false, nil)—— 后者与"锁确实未被占用"不可区分,调用方可能误以为可获取锁而进入临界区(正确性 bug)。 调用方应 errors.Is(err, ErrRedisNotReady) 区分"Redis 不可用"与"锁未占用"。 L-G 修复:用 .Result() 显式返回 Redis 错误(原 .Val() 吞错致故障被当"未占用")。
契约说明:锁操作有正确性影响(无锁进入临界区 = bug),故 Redis 不可用时显式返错; 与 cache.Get/Set 等数据操作(性能层、best-effort 静默 no-op)区分。
func LockWithPrefix ¶
func LockWithPrefix(ctx context.Context, key string, ttl time.Duration, prefix string) (bool, error)
LockWithPrefix 带前缀的分布式锁
func SetDefaultCacheManager ¶ added in v1.1.0
func SetDefaultCacheManager(m *CacheManager)
SetDefaultCacheManager 提升指定 CacheManager 为全局默认(atomic 置换,并发安全)。
func SetWithPrefix ¶
func SetWithPrefix(ctx context.Context, key string, value any, ttl time.Duration, prefix string) error
SetWithPrefix 带前缀的缓存设置
func UnlockByKey ¶
UnlockByKey 按键名释放锁(不安全,仅用于旧代码兼容) 注意: 此函数不检查 Token,任何客户端都能释放锁
func UnlockWithPrefix ¶
UnlockWithPrefix 带前缀的锁释放 注意: 此函数不检查 Token,仅用于向后兼容,建议使用 NewLock/Unlock 组合
func WithLock ¶
func WithLock(ctx context.Context, key string, ttl time.Duration, fn func(context.Context) error) error
WithLock 使用分布式锁执行函数(自动管理锁)。 参数: key 锁名称,ttl 锁定时长,fn 业务函数 注意: 如果任务执行时间超过 ttl,需要设置更长的 ttl 或使用 WithLockAutoExtend。
解锁用独立 Background ctx(C1a 一致性修复):fn 返回或 panic 后,原 ctx 可能已被 调用方取消,用其解锁会失败导致锁泄漏到 TTL。fn panic 时 defer 也保证解锁执行。
func WithLockAutoExtend ¶
func WithLockAutoExtend(ctx context.Context, key string, initialTTL time.Duration, extendInterval time.Duration, fn func(context.Context) error) error
WithLockAutoExtend 使用分布式锁执行函数(自动续期)。 参数: key 锁名称,initialTTL 初始锁定时长,extendInterval 续期间隔,fn 业务函数
并发安全说明(C1a 修复):续期 goroutine 与父用"父关停 + 子 ack"双 channel 协调—— 父用 close(stop) 通知子退出(close 由唯一所有者执行,安全),子用 close(finished) ack。 避免旧实现 done 无缓冲 + 子 defer close(done) + 父 done<-struct{}{} 的 send-on-closed panic (ctx 取消或 ExtendLock 失败时 done 已 closed,父再 send 即 panic,Unlock 不执行、锁泄漏到 TTL)。 Unlock 用 context.Background() 派生超时,避免原 ctx 已取消致 Unlock 失败再泄漏。
Types ¶
type CacheManager ¶ added in v1.1.0
type CacheManager struct {
// contains filtered or unexported fields
}
CacheManager 缓存管理器(#10)。照 database.Manager 模式: 实例化 + DefaultCache 全局默认 + 包级 facade 代理,支持测试注入 mock 实现。
func GetDefaultCache ¶ added in v1.2.0
func GetDefaultCache() *CacheManager
GetDefaultCache 返回全局默认缓存管理器(并发安全,CK3 修复)。
func NewCacheManager ¶ added in v1.1.0
func NewCacheManager() *CacheManager
NewCacheManager 创建缓存管理器实例。
func SwapDefaultCacheManager ¶ added in v1.4.0
func SwapDefaultCacheManager(m *CacheManager) *CacheManager
SwapDefaultCacheManager 将指定 CacheManager 置为全局默认,返回被替换的旧 Manager。 旧 Manager 不会被关闭,供 App 初始化这类需要失败回滚的生命周期流程暂存(照 SwapDefaultRedisManager / SwapDefaultStorageManager 模式)。nil 被忽略,返回当前默认。
func (*CacheManager) Get ¶ added in v1.1.0
func (m *CacheManager) Get() CacheService
Get 返回缓存服务(未初始化时延迟初始化)。
func (*CacheManager) Init ¶ added in v1.1.0
func (m *CacheManager) Init()
Init 初始化缓存服务(基于 DefaultRedis 的客户端)。
func (*CacheManager) InitWithRedis ¶ added in v1.4.0
func (m *CacheManager) InitWithRedis(client *redis.Client)
InitWithRedis 用指定 Redis 客户端初始化缓存服务(多 Redis/测试隔离)。
func (*CacheManager) Set ¶ added in v1.1.0
func (m *CacheManager) Set(svc CacheService)
Set 设置缓存服务实现(用于注入 mock 或自定义实现)。
type CacheService ¶
type CacheService interface {
// Get 获取缓存值,命中则反序列化到 dest 并返回 (true, nil);未命中返回 (false, nil);
// Redis 未就绪、命令错误或反序列化失败返回 (false, err)。调用方须显式处理错误。
Get(ctx context.Context, key string, dest any) (bool, error)
// Set 设置缓存值
Set(ctx context.Context, key string, value any, ttl time.Duration) error
// Delete 删除缓存
Delete(ctx context.Context, key string) error
// DeleteByPattern 按模式删除缓存
DeleteByPattern(ctx context.Context, pattern string) error
// Exists 检查缓存是否存在;未命中返回 (false, nil),后端错误返回 (false, err)。
Exists(ctx context.Context, key string) (bool, error)
}
CacheService 缓存服务接口
func NewRedisCache ¶
func NewRedisCache() CacheService
NewRedisCache 创建 Redis 缓存实例(懒取全局 Redis,兼容 standalone 用法)。
func NewRedisCacheWithRedis ¶ added in v1.4.0
func NewRedisCacheWithRedis(client *redis.Client) CacheService
NewRedisCacheWithRedis 创建使用指定 Redis 客户端的缓存实例(多 Redis/测试隔离)。
type KeyBuilder ¶
type KeyBuilder struct {
// contains filtered or unexported fields
}
KeyBuilder 缓存键名构建器(CK2 修复:mu 保护并发访问)。 使用场景: 多个小项目共用一台 Redis 服务器,每个项目设置不同前缀
func GetKeyBuilder ¶
func GetKeyBuilder() *KeyBuilder
GetKeyBuilder 获取全局键名构建器,未初始化时用 sync.Once 自动初始化一次(M13)。
func (*KeyBuilder) Build ¶
func (kb *KeyBuilder) Build(key string) string
Build 构建完整键名(CK2 修复:mu 读保护)。 格式: {cacheType}{separator}{prefix}{separator}{key} 示例: kb.Build("user:1") -> "cache:site_a:user:1"
func (*KeyBuilder) BuildCounter ¶
func (kb *KeyBuilder) BuildCounter(key string) string
BuildCounter 构建计数器键名(CK2 修复:mu 读保护)。 格式: "counter{separator}{prefix}{separator}{key}"
func (*KeyBuilder) BuildLock ¶
func (kb *KeyBuilder) BuildLock(key string) string
BuildLock 构建分布式锁键名(CK2 修复:mu 读保护)。 格式: "lock{separator}{prefix}{separator}{key}"
func (*KeyBuilder) BuildPattern ¶
func (kb *KeyBuilder) BuildPattern(pattern string) string
BuildPattern 构建匹配模式(用于 SCAN/Keys)(CK2 修复:mu 读保护)。 示例: kb.BuildPattern("user:*") -> "cache:site_a:user:*"
func (*KeyBuilder) BuildPerm ¶
func (kb *KeyBuilder) BuildPerm(key string) string
BuildPerm 构建永久缓存键名(CK2 修复:mu 读保护)。 格式: "perm{separator}{prefix}{separator}{key}"
func (*KeyBuilder) BuildSession ¶
func (kb *KeyBuilder) BuildSession(key string) string
BuildSession 构建会话键名(CK2 修复:mu 读保护)。 格式: "session{separator}{prefix}{separator}{key}"
func (*KeyBuilder) BuildTemp ¶
func (kb *KeyBuilder) BuildTemp(key string) string
BuildTemp 构建临时缓存键名(CK2 修复:mu 读保护)。 格式: "temp{separator}{prefix}{separator}{key}"
func (*KeyBuilder) GetPrefix ¶
func (kb *KeyBuilder) GetPrefix() string
GetPrefix 获取当前前缀(CK2 修复:mu 读保护)。
func (*KeyBuilder) SetPrefix ¶
func (kb *KeyBuilder) SetPrefix(prefix string) *KeyBuilder
SetPrefix 动态设置前缀(CK2 修复:mu 写保护,并发安全)。
type KeyBuilderOption ¶
type KeyBuilderOption func(*KeyBuilder)
KeyBuilderOption 配置选项
func WithCacheType ¶
func WithCacheType(cacheType string) KeyBuilderOption
WithCacheType 设置缓存类型标识 示例: WithCacheType("session") -> "session:site_a:user:1"
func WithPrefix ¶
func WithPrefix(prefix string) KeyBuilderOption
WithPrefix 设置前缀(项目/站点别名) 示例: WithPrefix("site_a") -> 所有 key 自动添加 "site_a" 前缀
func WithSeparator ¶
func WithSeparator(separator string) KeyBuilderOption
WithSeparator 设置分隔符 示例: WithSeparator(":") -> "site_a:user:1"
type LockToken ¶
LockToken 锁令牌(用于安全释放锁)。
安全说明(C1d 设计局限):Token 是随机 UUID(非单调递增的 fencing token)。 本实现基于 Redis SET PX + Lua CAS,保证"持有者才能解锁/续期",但**无法防 TTL 到期后的 双 worker 并发**:若 worker A 因 GC/网络停滞超过 TTL,锁过期后 worker B 获得锁, A 恢复后仍可能写过期数据。完整的 fencing token 防护需:① 用 Redis INCR 生成单调 token, ② 下游存储层(DB/外部服务)记录已见最大 token 并拒绝旧 token 写入。 框架无法单方面保证②,需下游配合,故本类型仅提供 UUID token。对 TTL 到期敏感的场景, 请确保 ttl >> 业务最长执行时间,或下游实现 fencing token 校验。