封装的方法类
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package uniquex
|
||||
|
||||
// Version: 2023年6月12日18:59:16
|
||||
|
||||
/**
|
||||
说明:
|
||||
1. 这是基于redis的全局锁
|
||||
2. 只要没释放锁会自动的续期,不用考虑锁被提前释放的问题
|
||||
3. 允许自定义超时时间
|
||||
**/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
type uniquex struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
redis *redis.Client
|
||||
uniqueKey string
|
||||
uuid string
|
||||
}
|
||||
|
||||
const tokenValidTime = time.Second * 5
|
||||
|
||||
func NewUniquex(ctx context.Context, redis *redis.Client, uniqueKey string) *uniquex {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
// 获取Token
|
||||
return &uniquex{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
redis: redis,
|
||||
uniqueKey: uniqueKey,
|
||||
uuid: uuid.NewV4().String(),
|
||||
}
|
||||
}
|
||||
|
||||
func (u *uniquex) Lock() error {
|
||||
// 获取Token
|
||||
b, err := u.redis.SetNX(u.ctx, u.uniqueKey, u.uuid, tokenValidTime).Result()
|
||||
if !b {
|
||||
return err
|
||||
}
|
||||
|
||||
go u.refreshToken()
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (u *uniquex) Unlock() {
|
||||
u.cancel()
|
||||
|
||||
// 释放Token
|
||||
script := `
|
||||
local token = redis.call('get',KEYS[1]);
|
||||
if token == ARGV[1]
|
||||
then
|
||||
redis.call('del',KEYS[1]);
|
||||
return 'SUCCESS';
|
||||
end;
|
||||
return 'ERROR'
|
||||
`
|
||||
u.redis.Eval(u.ctx, script, []string{u.uniqueKey}, u.uuid)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 刷新Token
|
||||
func (u *uniquex) refreshToken() {
|
||||
script := `
|
||||
local token = redis.call('get',KEYS[1])
|
||||
if token == ARGV[1]
|
||||
then
|
||||
redis.call('set',KEYS[1],ARGV[2],ARGV[1]);
|
||||
return 'SUCCESS';
|
||||
end;
|
||||
return 'ERROR';
|
||||
`
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
select {
|
||||
case <-u.ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
u.redis.Eval(u.ctx, script, []string{u.uniqueKey}, u.uuid, tokenValidTime.Seconds())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user