// Save a new item into the cache. func (r *Redis) Set(item kit.CacheItem) Error { key := item.GetKey() if key == "" { return kit.AppError{Code: "empty_key"} } key = r.key(key) if item.IsExpired() { return kit.AppError{Code: "item_expired"} } expireSeconds := 0 if expires := item.GetExpiresAt(); !expires.IsZero() { seconds := expires.Sub(time.Now()).Seconds() if seconds > 0 && seconds < 1 { return kit.AppError{Code: "item_expired"} } expireSeconds = int(seconds) } conn := r.pool.Get() defer conn.Close() value, err := item.ToString() if err != nil { return kit.AppError{ Code: "cacheitem_tostring_error", Message: err.Error(), Errors: []error{err}, } } if value == "" { return kit.AppError{Code: "empty_value"} } conn.Send("SET", key, value) if expireSeconds > 0 { conn.Send("EXPIRE", key, expireSeconds) } if tags := item.GetTags(); tags != nil { tagKey := r.tagKey(key) conn.Send("SET", tagKey, strings.Join(tags, ";")) if expireSeconds > 0 { conn.Send("EXPIRE", tagKey, expireSeconds) } } if err := conn.Flush(); err != nil { return redisErr(err) } return nil }
// Retrieve a cache item from the cache. func (fs *Fs) Get(key string, items ...kit.CacheItem) (kit.CacheItem, apperror.Error) { var item kit.CacheItem = &StrItem{} if items != nil { if len(items) != 1 { return nil, &apperror.Err{ Code: "invalid_item", Message: "You must specify one item only", } } item = items[0] } key = fs.key(key) if key == "" { return nil, apperror.New("empty_key") } exists, err := utils.FileExists(fs.keyPath(key)) if err != nil { return nil, err } if !exists { return nil, nil } metaContent, err := utils.ReadFile(fs.keyMetaPath(key)) if err != nil { return nil, err } if err := json.Unmarshal(metaContent, &item); err != nil { return nil, apperror.Wrap(err, "metadata_unmarshal_error") } // Reset ExpiresAt if it is zero, since json.Unmarshal produces // a time.Time which is not exactly equal to the zero value. if item.GetExpiresAt().IsZero() { item.SetExpiresAt(time.Time{}) } content, err := utils.ReadFile(fs.keyPath(key)) if err != nil { return nil, err } if err := item.FromString(string(content)); err != nil { return nil, apperror.Wrap(err, "cacheitem_fromstring_error") } // Return nil if item is expired. if item.IsExpired() { return nil, nil } return item, nil }
// Save a new item into the cache. func (fs *Fs) Set(item kit.CacheItem) apperror.Error { key := fs.key(item.GetKey()) if key == "" { return apperror.New("empty_key") } if item.IsExpired() { return apperror.New("item_expired") } value, err := item.ToString() if err != nil { return apperror.Wrap(err, "cacheitem_tostring_error") } if value == "" { return apperror.New("empty_value") } // Marshal metadata. tmpVal := item.GetValue() item.SetValue(nil) js, err2 := json.Marshal(item) if err2 != nil { return apperror.Wrap(err2, "json_marshal_error") } item.SetValue(tmpVal) if err := utils.WriteFile(fs.keyPath(key), []byte(value), false); err != nil { return err } if err := utils.WriteFile(fs.keyMetaPath(key), js, false); err != nil { return err } return nil }
// Retrieve a cache item from the cache. func (r *Redis) Get(key string, items ...kit.CacheItem) (kit.CacheItem, Error) { var item kit.CacheItem = &StrItem{} if items != nil { if len(items) != 1 { return nil, kit.AppError{ Code: "invalid_item", Message: "You must specify one item only", Internal: true, } } item = items[0] } if key == "" { return nil, kit.AppError{Code: "empty_key"} } item.SetKey(key) key = r.key(key) conn := r.pool.Get() defer conn.Close() result, err := redis.Strings(conn.Do("MGET", key, r.tagKey(key))) if err != nil { return nil, redisErr(err) } // Retrieve the value. if result[0] == "" { return nil, nil } if err := item.FromString(result[0]); err != nil { return nil, kit.AppError{ Code: "cacheitem_fromstring_error", Message: err.Error(), Errors: []error{err}, } } // Parse and set tags. if result[1] != "" { item.SetTags(strings.Split(result[1], ";")) } // Now get the ttl. ttl, err := redis.Int(conn.Do("TTL", key)) if err == nil && ttl > 0 { expires := time.Now().Add(time.Duration(ttl) * time.Second) item.SetExpiresAt(expires) } else if err != nil && err != redis.ErrNil { return nil, redisErr(err) } // Return nil if item is expired. if item.IsExpired() { return nil, nil } return item, nil }