- update lock

master
李光春 2 years ago
parent efa2675704
commit 88afe3db07

@ -0,0 +1,76 @@
package golock
import (
"context"
"errors"
"fmt"
"go.etcd.io/etcd/client/v3"
)
type LockEtcd struct {
etcdClient *clientv3.Client // 驱动
}
func NewLockEtcd(etcdClient *clientv3.Client) *LockEtcd {
return &LockEtcd{etcdClient: etcdClient}
}
// Lock 上锁
// key 锁名
// val 锁内容
// ttl 锁过期时间
func (e *LockEtcd) Lock(key string, val string, ttl int64) (string, error) {
if ttl <= 0 {
return "", errors.New("长期请使用 LockForever 方法")
}
// 1、获取
get, err := e.etcdClient.Get(context.Background(), key)
if err != nil {
return "", errors.New("获取异常")
}
if len(get.Kvs) > 0 {
return "", errors.New("上锁失败,已存在")
}
// 2、申请一个lease(租约)
lease := clientv3.NewLease(e.etcdClient)
// 3、申请一个*秒的租约
leaseGrantResp, err := lease.Grant(context.TODO(), ttl)
if err != nil {
return "", errors.New(fmt.Sprintf("申请租约失败 %s", err))
}
// 5、获得kv api子集
kv := clientv3.NewKV(e.etcdClient)
// 4、设置
kv.Put(context.TODO(), key, val, clientv3.WithLease(leaseGrantResp.ID))
if err != nil {
return "", errors.New("上锁失败")
}
return val, nil
}
// Unlock 解锁
// key 锁名
func (e *LockEtcd) Unlock(key string) error {
_, err := e.etcdClient.Delete(context.Background(), key)
return err
}
// LockForever 永远上锁
// key 锁名
// val 锁内容
func (e *LockEtcd) LockForever(key string, val string) (string, error) {
// 1、获取
get, err := e.etcdClient.Get(context.Background(), key)
if err != nil {
return "", errors.New("获取异常")
}
if len(get.Kvs) > 0 {
return "", errors.New("上锁失败,已存在")
}
// 2、设置
e.etcdClient.Put(context.TODO(), key, val)
if err != nil {
return "", errors.New("上锁失败")
}
return val, nil
}

@ -0,0 +1,28 @@
package golock
type Lock struct {
c chan struct{}
}
func NewLock() Lock {
l := Lock{}
l.c = make(chan struct{}, 1)
l.c <- struct{}{}
return l
}
// Lock 上锁
func (l *Lock) Lock() bool {
lockResult := false
select {
case <-l.c:
lockResult = true
default:
}
return lockResult
}
// Unlock 解锁
func (l *Lock) Unlock() {
l.c <- struct{}{}
}

@ -1,46 +1,67 @@
package golock
import (
"go.dtapp.net/library/utils/dorm"
"context"
"errors"
"github.com/go-redis/redis/v8"
"time"
)
type ConfigLockRedis struct {
Key string
KeyContent string
ExpirationTime time.Duration
}
type LockRedis struct {
config ConfigLockRedis
db *dorm.RedisClient
redisClient *redis.Client // 驱动
}
func NewLockRedis(db *dorm.RedisClient) *LockRedis {
return &LockRedis{db: db}
func NewLockRedis(redisClient *redis.Client) *LockRedis {
return &LockRedis{redisClient: redisClient}
}
// Lock 上锁
func (lockRedis *LockRedis) Lock() bool {
judgeCache := lockRedis.db.NewStringOperation().Get(lockRedis.config.Key).UnwrapOr("")
if judgeCache != "" {
return true
// key 锁名
// val 锁内容
// ttl 锁过期时间
func (r *LockRedis) Lock(key string, val string, ttl int64) (string, error) {
if ttl <= 0 {
return "", errors.New("长期请使用 LockForever 方法")
}
// 1、获取
get, err := r.redisClient.Get(context.Background(), key).Result()
if err != nil {
return "", errors.New("获取异常")
}
if get != "" {
return "", errors.New("上锁失败,已存在")
}
lockRedis.db.NewStringOperation().Set(lockRedis.config.Key, lockRedis.config.KeyContent, dorm.WithExpire(lockRedis.config.ExpirationTime))
return true
// 2、设置
err = r.redisClient.Set(context.Background(), key, val, time.Duration(ttl)).Err()
if err != nil {
return "", errors.New("上锁失败")
}
return val, nil
}
// Unlock Lock 解锁
func (lockRedis *LockRedis) Unlock() {
lockRedis.db.NewStringOperation().Del(lockRedis.config.Key)
// Unlock 解锁
// key 锁名
func (r *LockRedis) Unlock(key string) error {
_, err := r.redisClient.Del(context.Background(), key).Result()
return err
}
// LockForever 永远上锁
func (lockRedis *LockRedis) LockForever() bool {
judgeCache := lockRedis.db.NewStringOperation().Get(lockRedis.config.Key).UnwrapOr("")
if judgeCache != "" {
return true
// key 锁名
// val 锁内容
func (r *LockRedis) LockForever(key string, val string) (string, error) {
// 1、获取
get, err := r.redisClient.Get(context.Background(), key).Result()
if err != nil {
return "", errors.New("获取异常")
}
if get != "" {
return "", errors.New("上锁失败,已存在")
}
// 2、设置
err = r.redisClient.Set(context.Background(), key, val, 0).Err()
if err != nil {
return "", errors.New("上锁失败")
}
lockRedis.db.NewStringOperation().Set(lockRedis.config.Key, lockRedis.config.KeyContent)
return true
return val, nil
}

@ -0,0 +1 @@
package golock
Loading…
Cancel
Save