优化全局锁

This commit is contained in:
Yun
2023-08-29 10:27:36 +08:00
parent 9955204f18
commit 1d37696815
3 changed files with 63 additions and 8 deletions
+2
View File
@@ -219,6 +219,8 @@ func (c *cluster) getTask() {
// 执行任务 // 执行任务
func doTask(ctx context.Context, red *redis.Client, taskId string) { func doTask(ctx context.Context, red *redis.Client, taskId string) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
+17 -6
View File
@@ -3,6 +3,7 @@ package lockx
import ( import (
"context" "context"
"fmt" "fmt"
"log"
"time" "time"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
@@ -32,8 +33,10 @@ func (g *globalLock) Lock() bool {
return redis.call('set',KEYS[1],ARGV[1],'EX',ARGV[2]) return redis.call('set',KEYS[1],ARGV[1],'EX',ARGV[2])
` `
resp, _ := g.redis.Eval(g.ctx, script, []string{g.uniqueKey}, g.value, 10).Result() resp, err := g.redis.Eval(g.ctx, script, []string{g.uniqueKey}, g.value, 10).Result()
if resp != "OK" {
log.Println("globalLock Lock", resp, err)
}
return resp == "OK" return resp == "OK"
} }
@@ -55,12 +58,16 @@ func (g *globalLock) Unlock() bool {
local token = redis.call('get',KEYS[1]) local token = redis.call('get',KEYS[1])
if token == ARGV[1] if token == ARGV[1]
then then
return redis.call('del',KEYS[1]) redis.call('del',KEYS[1])
return 'OK'
end end
return 'ERROR' return 'ERROR'
` `
resp, _ := g.redis.Eval(g.ctx, script, []string{g.uniqueKey}, g.value).Result() resp, err := g.redis.Eval(g.ctx, script, []string{g.uniqueKey}, g.value).Result()
if resp != "OK" {
log.Println("globalLock Unlock", resp, err)
}
return resp == "OK" return resp == "OK"
} }
@@ -88,11 +95,15 @@ func (g *globalLock) refresh() bool {
local token = redis.call('get',KEYS[1]) local token = redis.call('get',KEYS[1])
if token == ARGV[1] if token == ARGV[1]
then then
return redis.call('set',KEYS[1],ARGV[1],'EX',ARGV[2]) redis.call('set',KEYS[1],ARGV[1],'EX',ARGV[2])
return 'OK'
end end
return 'ERROR' return 'ERROR'
` `
resp, _ := g.redis.Eval(g.ctx, script, []string{g.uniqueKey}, g.value, 5).Result() resp, err := g.redis.Eval(g.ctx, script, []string{g.uniqueKey}, g.value, 5).Result()
if resp != "OK" {
log.Println("globalLock refresh", resp, err)
}
return resp == "OK" return resp == "OK"
} }
+42
View File
@@ -0,0 +1,42 @@
package lockx_test
import (
"context"
"fmt"
"testing"
"code.yun.ink/open/timer/lockx"
"github.com/go-redis/redis/v8"
)
var Redis *redis.Client
func TestMain(m *testing.M) {
client := redis.NewClient(&redis.Options{
Addr: "127.0.0.1" + ":" + "6379",
Password: "", // no password set
DB: 0, // use default DB
})
if client == nil {
fmt.Println("redis init error")
return
}
Redis = client
}
func TestLockx(t *testing.T) {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
lock := lockx.NewGlobalLock(ctx, Redis, "lockx:test")
if !lock.Lock() {
t.Log("lock error")
}
defer lock.Unlock()
lock.Refresh()
t.Log("doing")
}