package lock import ( "context" "errors" "cache" "time" "github.com/go-redis/redis/v8" "github.com/google/uuid" ) const ( DefaultExpirationTime = 5 * time.Second RenewInterval = DefaultExpirationTime / 2 // 续租间隔为锁过期时间的一半 LuaCheckAndDelKey = ` if(redis.call('get',KEYS[1])==ARGV[1]) then return redis.call('del',KEYS[1]) else return 0 end ` LuaCheckAndRenewKey = ` if(redis.call('get',KEYS[1])==ARGV[1]) then return redis.call('expire',KEYS[1],ARGV[2]) else return 0 end ` ) type RedisLock struct { key string val string expiration time.Duration cli *redis.Client script *redis.Script // 用于解锁的 Lua 脚本 renewScript *redis.Script // 用于续租的 Lua 脚本 stopChan chan struct{} // 用于停止续租 goroutine } func NewRedisLock(key string) *RedisLock { val := uuid.New().String() return &RedisLock{ key: key, val: val, expiration: DefaultExpirationTime, cli: cache.RedisV8Client, script: redis.NewScript(LuaCheckAndDelKey), renewScript: redis.NewScript(LuaCheckAndRenewKey), stopChan: make(chan struct{}), } } func (r *RedisLock) Lock(ctx context.Context)...