goRedisDLM/worker/rpc.go

73 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package worker
import (
"context"
"errors"
"fmt"
"goRedisDLM/engine"
"goRedisDLM/redisLock"
"log"
"strconv"
"github.com/go-redis/redis/v8"
)
type Inventory struct {
Client *redis.Client
}
func (i *Inventory) Work(request engine.Request, response *engine.Response) error {
ctx := context.Background()
//lock := redisLock.CreateRedisLock(i.Client, ctx, request.Dlock, 100)
lock := redisLock.NewRedisLock(i.Client, ctx, "test_key", redisLock.WithBlock(),
redisLock.WithMaxWaitTime(20), redisLock.WithExpireTime(5))
lock.Lock()
//time.Sleep(time.Duration(rand.Int31n(100)) * time.Millisecond)
get := i.Client.Get(ctx, "inventory")
log.Printf("%s\n", get)
inventory, err := strconv.Atoi(get.Val())
if err != nil {
goto Error
}
inventory = inventory - 1
if inventory >= 0 {
//这里应该使用lua脚本再检测一下当前是否获取到锁获取到之后再进行扣减。类似双检加锁的思想因为此时可能会续期失败。
//i.Client.Set(ctx, "inventory", fmt.Sprintf("%d", inventory), redis.KeepTTL)
//script := `if redis.call('hexists',KEYS[1],ARGV[1]) == 1 then return redis.call('set',KEYS[2],ARGV[2])
// else return 0 end`
//
//val := i.Client.Eval(ctx, script, []string{request.Dlock, "inventory"}, value.String(), inventory).Val()
if lock.IsHeldByCurrent() {
setString := fmt.Sprintf("%d", inventory)
if i.Client.Set(ctx, "inventory", setString, redis.KeepTTL).Val() != "OK" {
log.Println("error set inventory")
err = errors.New("inventory err")
goto Error
}
} else {
//任务执行失败需要通知调用者让调用者自己决策是否需要重新调度还是放弃这样worker和主线程实现了解偶
log.Println("error lock is not held")
err = errors.New("error lock is not held")
goto Error
}
} else {
log.Printf("error DLock error :%d\n", inventory)
err = errors.New("inventory err")
goto Error
}
lock.UnLock()
response.Id = request.Id
return nil
Error:
lock.UnLock()
return err
}