credis

package
v1.0.20 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2026 License: MIT Imports: 9 Imported by: 0

README

关键点:

获取锁:SET key token NX PX ttl,token 用框架自带的 cnuid.Next() 生成,保证唯一。
安全释放/续期:用 Lua 脚本先比对 token 再 del / pexpire,避免误删他人持有的锁。
看门狗自动续期:WithAutoRenew() 开启后,在 ttl/3 处自动续期,防止业务没跑完锁就过期;Unlock 或 ctx 取消时自动停止。
并发安全:用 sync.Mutex 保护 token 和看门狗状态。
提供的 API
NewLock(rdb, key, opts...) / NewLockWithInstance(key, opts...)(后者用全局 redis 组件实例,并自动拼接配置里的 PrefixKey)
TryLock(ctx):尝试一次,立即返回
Lock(ctx):阻塞重试直到成功或 ctx 结束
Unlock(ctx) / Renew(ctx)
WithLock(ctx, rdb, key, fn, opts...):获取→执行→自动释放 的便捷封装
选项:WithTTL、WithRetryInterval、WithAutoRenew
使用示例

import (
    "context"
    "time"
    credis "github.com/actorgo-game/actorgo/components/redis"
)

// 方式一:手动控制
lock := credis.NewLockWithInstance("order:1001", credis.WithTTL(10*time.Second), credis.WithAutoRenew())
if err := lock.Lock(context.Background()); err != nil {
    return err
}
defer lock.Unlock(context.Background())
// ... 临界区业务 ...

// 方式二:便捷封装
err := credis.WithLock(ctx, credis.Instance(), "order:1001", func() error {
    // ... 临界区业务 ...
    return nil
}, credis.WithTTL(10*time.Second))

锁依赖 redis 组件已初始化(即 credis.NewComponent() 已注册并 Init)。

Documentation

Index

Constants

View Source
const (
	Name = "redis_component"
)

Variables

View Source
var (
	// ErrLockNotObtained 在规定时间/重试次数内未能获取到锁时返回
	ErrLockNotObtained = errors.New("redis lock: lock not obtained")
	// ErrLockNotHeld 释放或续期时,发现锁已不属于当前持有者(已过期或被他人持有)
	ErrLockNotHeld = errors.New("redis lock: lock not held")
	// ErrClientNil redis client 为空(通常是 redis 组件未初始化)
	ErrClientNil = errors.New("redis lock: redis client is nil")
)

Functions

func Instance

func Instance() *redis.Client

func WithLock added in v1.0.20

func WithLock(ctx context.Context, rdb *redis.Client, key string, fn func() error, opts ...Option) error

WithLock 是一个便捷封装:获取锁 -> 执行 fn -> 释放锁。 获取锁失败时直接返回错误,不会执行 fn。

Types

type Component

type Component struct {
	cfacade.Component
	// contains filtered or unexported fields
}

func NewComponent

func NewComponent() *Component

func (*Component) Init

func (s *Component) Init()

func (*Component) Name

func (*Component) Name() string

func (*Component) OnAfterInit

func (s *Component) OnAfterInit()

func (*Component) OnStop

func (s *Component) OnStop()

type Lock added in v1.0.20

type Lock struct {
	// contains filtered or unexported fields
}

Lock 基于 Redis 实现的分布式锁。

通过 SET key token NX PX 获取锁,使用唯一 token 标识持有者, 释放/续期均通过 Lua 脚本校验 token,保证只有持有者才能操作,避免误删。 可选开启看门狗(watchdog)在持锁期间自动续期,防止业务未结束锁就过期。

func NewLock added in v1.0.20

func NewLock(rdb *redis.Client, key string, opts ...Option) *Lock

NewLock 使用指定的 redis client 创建一把分布式锁。

func NewLockWithInstance added in v1.0.20

func NewLockWithInstance(key string, opts ...Option) *Lock

NewLockWithInstance 使用全局 redis 组件实例创建分布式锁, 并自动拼接 redis 组件配置的 PrefixKey 前缀。

func (*Lock) Key added in v1.0.20

func (l *Lock) Key() string

Key 返回锁对应的 redis key。

func (*Lock) Lock added in v1.0.20

func (l *Lock) Lock(ctx context.Context) error

Lock 阻塞式获取锁,按 retryInterval 重试,直到获取成功或 ctx 结束。 若 ctx 超时/取消仍未获取到,返回 ctx.Err() 或 ErrLockNotObtained。

func (*Lock) Renew added in v1.0.20

func (l *Lock) Renew(ctx context.Context) error

Renew 手动续期,将锁的过期时间重设为 ttl。 仅当前 token 持有锁时有效,否则返回 ErrLockNotHeld。

func (*Lock) TryLock added in v1.0.20

func (l *Lock) TryLock(ctx context.Context) error

TryLock 尝试获取一次锁,立即返回。 获取成功返回 nil,未获取到返回 ErrLockNotObtained。

func (*Lock) Unlock added in v1.0.20

func (l *Lock) Unlock(ctx context.Context) error

Unlock 释放锁,仅当当前 token 仍持有锁时才会删除。 若锁已过期或被他人持有,返回 ErrLockNotHeld。

type Option added in v1.0.20

type Option func(*Lock)

Option 配置分布式锁的可选项

func WithAutoRenew added in v1.0.20

func WithAutoRenew() Option

WithAutoRenew 开启看门狗,在成功获取锁后自动定时续期, 直到调用 Unlock 或获取锁时使用的 ctx 被取消。

func WithRetryInterval added in v1.0.20

func WithRetryInterval(interval time.Duration) Option

WithRetryInterval 设置阻塞获取锁(Lock)时的重试间隔,默认 100ms。

func WithTTL added in v1.0.20

func WithTTL(ttl time.Duration) Option

WithTTL 设置锁的过期时间,默认 30s。

Jump to

Keyboard shortcuts

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