github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/infura/distrlock/redis_distr_state_lock.go (about) 1 package distrlock 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/fibonacci-chain/fbc/libs/tendermint/libs/log" 8 "github.com/go-redis/redis/v8" 9 ) 10 11 var unlockScript = redis.NewScript(` 12 if redis.call("get", KEYS[1]) == ARGV[1] 13 then 14 return redis.call("del", KEYS[1]) 15 else 16 return 0 17 end 18 `) 19 20 var unlockScriptWithState = redis.NewScript(` 21 if redis.call("get", KEYS[1]) == ARGV[1] 22 then 23 redis.call("set", KEYS[2], ARGV[2]) 24 return redis.call("del", KEYS[1]) 25 else 26 return 0 27 end 28 `) 29 30 type RedisDistributeStateService struct { 31 client *redis.Client 32 logger log.Logger 33 lockerID string // unique identifier of locker 34 } 35 36 func NewRedisDistributeStateService(url string, pass string, db int, logger log.Logger, lockerID string) (*RedisDistributeStateService, error) { 37 client := redis.NewClient(&redis.Options{ 38 Addr: url, 39 Password: pass, // no password set 40 DB: db, // use select DB 41 }) 42 43 s := &RedisDistributeStateService{ 44 client: client, 45 logger: logger, 46 lockerID: lockerID, 47 } 48 49 return s, nil 50 } 51 52 func (s *RedisDistributeStateService) GetLockerID() string { 53 return s.lockerID 54 } 55 56 func (s *RedisDistributeStateService) GetDistState(stateKey string) string { 57 state, _ := s.client.Get(context.Background(), stateKey).Result() 58 return state 59 } 60 61 func (s *RedisDistributeStateService) SetDistState(stateKey string, stateValue string) error { 62 err := s.client.Set(context.Background(), stateKey, stateValue, 0).Err() 63 return err 64 } 65 66 func (s *RedisDistributeStateService) FetchDistLock(lockKey string, locker string, expiredInMS int) (bool, error) { 67 success, err := s.client.SetNX(context.Background(), lockKey, locker, 68 time.Duration(expiredInMS)*time.Millisecond).Result() 69 return success, err 70 } 71 72 func (s *RedisDistributeStateService) ReleaseDistLock(lockKey string, locker string) (bool, error) { 73 replyStatus, err := unlockScript.Run(context.Background(), s.client, []string{lockKey}, locker).Int() 74 return err == nil && replyStatus == 1, err 75 } 76 77 func (s *RedisDistributeStateService) UnlockDistLockWithState(lockKey string, locker string, stateKey string, stateValue string) (bool, error) { 78 replyStatus, err := unlockScriptWithState.Run(context.Background(), s.client, []string{lockKey, stateKey}, locker, stateValue).Int() 79 return err == nil && replyStatus == 1, err 80 }