package redisutils import ( "time" "github.com/fiskerinc/cloud-services/pkg/redis" "github.com/pkg/errors" ) var ( ErrCacheDoesntExist = errors.New("key doesn't exist") ErrWrongResponseFormat = errors.New("wrong response format") ) type CachedSet struct { redis redis.Client } func (s *CachedSet) SetConnection(client redis.Client) { s.redis = client } func (s *CachedSet) GetCachedSet(key string) (map[string]struct{}, error) { batch := redis.NewRedisBatchCommands() batch.Add("EXISTS", key) batch.Add("SMEMBERS", key) resultsI, err := s.redis.ExecuteBatch(batch) if err != nil { return nil, err } results, ok := resultsI.([]interface{}) if !ok || len(results) != 2 { return nil, errResponseFormat("[2]interface{}", resultsI) } keyExists, ok := results[0].(int64) if !ok { return nil, errResponseFormat("int64", results[0]) } if keyExists == 0 { return nil, ErrCacheDoesntExist } cacheRes, ok := results[1].([]interface{}) if !ok { return nil, errResponseFormat("[]interface{}", results[1]) } cacheSet := make(map[string]struct{}, len(cacheRes)) for _, signal := range cacheRes { s, ok := signal.([]byte) if !ok { return nil, errResponseFormat("[]byte", signal) } cacheSet[string(s)] = struct{}{} } return cacheSet, nil } func (s *CachedSet) UpdateSetCache(key string, cacheValues []interface{}) error { saddCommand := append([]interface{}{"SADD", key}, cacheValues...) _, err := s.redis.Execute(saddCommand...) return err } func (s *CachedSet) CreateSetCache(key string, cacheValues []interface{}, expireTime time.Time) error { batch := redis.NewRedisBatchCommands() saddCommand := append([]interface{}{"SADD", key}, cacheValues...) batch.Add(saddCommand...) batch.Add("EXPIREAT", key, expireTime.Unix()) _, err := s.redis.ExecuteBatch(batch) return err } func errResponseFormat(expectedType string, got interface{}) error { return errors.WithStack( errors.WithMessagef(ErrWrongResponseFormat, "expected type: %s, got: %v", expectedType, got), ) }