github.com/okex/exchain@v1.8.0/libs/tendermint/delta/redis-cgi/cgi.go (about) 1 package redis_cgi 2 3 import ( 4 "context" 5 "fmt" 6 "github.com/go-redis/redis/v8" 7 "github.com/okex/exchain/libs/tendermint/libs/log" 8 "github.com/okex/exchain/libs/tendermint/types" 9 "sync" 10 "time" 11 ) 12 13 const ( 14 lockerExpire = 4 * time.Second 15 ) 16 17 var ( 18 mostRecentHeightKey string 19 deltaLockerKey string 20 ) 21 22 var once sync.Once 23 24 // init initialize the mostRecentHeightKey and deltaLockerKey 25 // the keys are based types.DeltaVersion, which can specified by user. 26 func (r *RedisClient) init() { 27 const ( 28 mostRecentHeight = "MostRecentHeight" 29 deltaLocker = "DeltaLocker" 30 ) 31 once.Do(func() { 32 mostRecentHeightKey = fmt.Sprintf("dds:%d:%s", types.DeltaVersion, mostRecentHeight) 33 deltaLockerKey = fmt.Sprintf("dds:%d:%s", types.DeltaVersion, deltaLocker) 34 }) 35 } 36 37 type RedisClient struct { 38 rdb *redis.Client 39 ttl time.Duration 40 logger log.Logger 41 } 42 43 func NewRedisClient(url, auth string, ttl time.Duration, db int, l log.Logger) *RedisClient { 44 rdb := redis.NewClient(&redis.Options{ 45 Addr: url, 46 Password: auth, // no password set 47 DB: db, // use select DB 48 }) 49 redisClient := RedisClient{rdb, ttl, l} 50 redisClient.init() 51 52 return &redisClient 53 } 54 55 func (r *RedisClient) GetLocker() bool { 56 res, err := r.rdb.SetNX(context.Background(), deltaLockerKey, true, lockerExpire).Result() 57 if err != nil { 58 r.logger.Error("GetLocker err", err) 59 return false 60 } 61 return res 62 } 63 64 func (r *RedisClient) ReleaseLocker() { 65 _, err := r.rdb.Del(context.Background(), deltaLockerKey).Result() 66 if err != nil { 67 r.logger.Error("Failed to Release Locker", "err", err) 68 } 69 } 70 71 // return bool: if change the value of latest_height, need to upload 72 func (r *RedisClient) ResetMostRecentHeightAfterUpload(targetHeight int64, upload func(int64) bool) (bool, int64, error) { 73 var res bool 74 mrh, err := r.rdb.Get(context.Background(), mostRecentHeightKey).Int64() 75 if err != nil && err != redis.Nil { 76 return res, mrh, err 77 } 78 79 if mrh < targetHeight && upload(mrh) { 80 err = r.rdb.Set(context.Background(), mostRecentHeightKey, targetHeight, 0).Err() 81 if err == nil { 82 res = true 83 r.logger.Info("Reset most recent height", "new-mrh", targetHeight, "old-mrh", mrh) 84 } else { 85 r.logger.Error("Failed to reset most recent height", 86 "target-mrh", targetHeight, 87 "existing-mrh", mrh, "err", err) 88 } 89 } 90 return res, mrh, err 91 } 92 93 func (r *RedisClient) SetBlock(height int64, bytes []byte) error { 94 if len(bytes) == 0 { 95 return fmt.Errorf("block is empty") 96 } 97 req := r.rdb.SetNX(context.Background(), genBlockKey(height), bytes, r.ttl) 98 return req.Err() 99 } 100 101 func (r *RedisClient) SetDeltas(height int64, bytes []byte) error { 102 if len(bytes) == 0 { 103 return fmt.Errorf("delta is empty") 104 } 105 req := r.rdb.SetNX(context.Background(), genDeltaKey(height), bytes, r.ttl) 106 return req.Err() 107 } 108 109 func (r *RedisClient) GetBlock(height int64) ([]byte, error) { 110 bytes, err := r.rdb.Get(context.Background(), genBlockKey(height)).Bytes() 111 if err == redis.Nil { 112 return nil, fmt.Errorf("get empty block") 113 } 114 if err != nil { 115 return nil, err 116 } 117 return bytes, nil 118 } 119 120 func (r *RedisClient) GetDeltas(height int64) ([]byte, error, int64) { 121 mrh := r.getMostRecentHeight() 122 bytes, err := r.rdb.Get(context.Background(), genDeltaKey(height)).Bytes() 123 if err == redis.Nil { 124 return nil, fmt.Errorf("get empty delta"), mrh 125 } 126 return bytes, err, mrh 127 } 128 129 func (r *RedisClient) getMostRecentHeight() (mrh int64) { 130 mrh = -1 131 h, err := r.rdb.Get(context.Background(), mostRecentHeightKey).Int64() 132 if err == nil { 133 mrh = h 134 } else if err == redis.Nil { 135 mrh = 0 136 } 137 return 138 } 139 140 func genBlockKey(height int64) string { 141 return fmt.Sprintf("BH:%d", height) 142 } 143 144 func genDeltaKey(height int64) string { 145 return fmt.Sprintf("DH-%d:%d", types.DeltaVersion, height) 146 }