代码拉取完成,页面将自动刷新
package lockers
import (
"fmt"
"github.com/go-redis/redis/v7"
"os"
"time"
)
// RedisDisLocker 基于redis的分布式锁
type RedisDisLocker struct {
rds *redis.Client
lockValue string
}
func NewRedisDisLocker(rds *redis.Client) (*RedisDisLocker, error) {
name, err := os.Hostname()
if err != nil {
name = fmt.Sprintf("unknow_%d", time.Now().UnixNano())
}
return &RedisDisLocker{
rds: rds,
lockValue: "locked_on_" + name,
}, nil
}
// Lock 尝试加锁 ttl: 秒级
func (l *RedisDisLocker) Lock(key string, ttl int64) (bool, error) {
_, err := l.rds.Do("set", key, l.lockValue, "NX", "EX", ttl).Result()
if err == redis.Nil {
return false, nil
} else if err != nil {
return false, err
}
return true, nil
}
// Release 释放锁
func (l *RedisDisLocker) Release(key string) error {
luaDelete := redis.NewScript(`if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end`)
_, err := luaDelete.Run(l.rds, []string{key}, l.lockValue).Result()
return err
}
// Delay 延长锁 ttl: 秒级
func (l *RedisDisLocker) Delay(key string, ttl int64) error {
luaRefresh := redis.NewScript(`if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("pexpire", KEYS[1], ARGV[2]) else return 0 end`)
_, err := luaRefresh.Run(l.rds, []string{key}, l.lockValue, ttl*1000).Result()
return err
}
// TTL 返回锁剩余时间 毫秒级
func (l *RedisDisLocker) TTL(key string) (int64, error) {
luaPTTL := redis.NewScript(`if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("pttl", KEYS[1]) else return -3 end`)
t, err := luaPTTL.Run(l.rds, []string{key}, l.lockValue).Result()
return t.(int64), err
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。