remote cache: new function to get/set cache items as byte arrays (#62916)

Signed-off-by: bergquist <carl.bergquist@gmail.com>
This commit is contained in:
Carl Bergquist
2023-02-06 13:08:03 +01:00
committed by GitHub
parent e3512ddd7e
commit 791b1001af
4 changed files with 94 additions and 27 deletions
+26 -13
View File
@@ -54,10 +54,9 @@ func (dc *databaseCache) internalRunGC() {
}
}
func (dc *databaseCache) Get(ctx context.Context, key string) (interface{}, error) {
func (dc *databaseCache) GetByteArray(ctx context.Context, key string) ([]byte, error) {
cacheHit := CacheData{}
item := &cachedItem{}
err := dc.SQLStore.WithDbSession(ctx, func(session *db.Session) error {
exist, err := session.Where("cache_key= ?", key).Get(&cacheHit)
@@ -80,23 +79,27 @@ func (dc *databaseCache) Get(ctx context.Context, key string) (interface{}, erro
}
}
if err = dc.codec.Decode(ctx, cacheHit.Data, item); err != nil {
return err
}
return nil
})
return cacheHit.Data, err
}
func (dc *databaseCache) Get(ctx context.Context, key string) (interface{}, error) {
bytes, err := dc.GetByteArray(ctx, key)
if err != nil {
return nil, err
}
item := &cachedItem{}
if err = dc.codec.Decode(ctx, bytes, item); err != nil {
return nil, err
}
return item.Val, err
}
func (dc *databaseCache) Set(ctx context.Context, key string, value interface{}, expire time.Duration) error {
item := &cachedItem{Val: value}
data, err := dc.codec.Encode(ctx, item)
if err != nil {
return err
}
func (dc *databaseCache) SetByteArray(ctx context.Context, key string, data []byte, expire time.Duration) error {
return dc.SQLStore.WithDbSession(ctx, func(session *db.Session) error {
var expiresInSeconds int64
if expire != 0 {
@@ -126,6 +129,16 @@ func (dc *databaseCache) Set(ctx context.Context, key string, value interface{},
})
}
func (dc *databaseCache) Set(ctx context.Context, key string, value interface{}, expire time.Duration) error {
item := &cachedItem{Val: value}
data, err := dc.codec.Encode(ctx, item)
if err != nil {
return err
}
return dc.SetByteArray(ctx, key, data, expire)
}
func (dc *databaseCache) Delete(ctx context.Context, key string) error {
return dc.SQLStore.WithDbSession(ctx, func(session *db.Session) error {
sql := "DELETE FROM cache_data WHERE cache_key=?"
+23 -8
View File
@@ -2,6 +2,7 @@ package remotecache
import (
"context"
"errors"
"time"
"github.com/bradfitz/gomemcache/memcache"
@@ -39,29 +40,29 @@ func (s *memcachedStorage) Set(ctx context.Context, key string, val interface{},
return err
}
return s.SetByteArray(ctx, key, bytes, expires)
}
// SetByteArray stores an byte array in the cache
func (s *memcachedStorage) SetByteArray(ctx context.Context, key string, data []byte, expires time.Duration) error {
var expiresInSeconds int64
if expires != 0 {
expiresInSeconds = int64(expires) / int64(time.Second)
}
memcachedItem := newItem(key, bytes, int32(expiresInSeconds))
memcachedItem := newItem(key, data, int32(expiresInSeconds))
return s.c.Set(memcachedItem)
}
// Get gets value by given key in the cache.
func (s *memcachedStorage) Get(ctx context.Context, key string) (interface{}, error) {
memcachedItem, err := s.c.Get(key)
if err != nil && err.Error() == "memcache: cache miss" {
return nil, ErrCacheItemNotFound
}
bytes, err := s.GetByteArray(ctx, key)
if err != nil {
return nil, err
}
item := &cachedItem{}
err = s.codec.Decode(ctx, memcachedItem.Value, item)
err = s.codec.Decode(ctx, bytes, item)
if err != nil {
return nil, err
}
@@ -69,6 +70,20 @@ func (s *memcachedStorage) Get(ctx context.Context, key string) (interface{}, er
return item.Val, nil
}
// GetByteArray returns the cached value as an byte array
func (s *memcachedStorage) GetByteArray(ctx context.Context, key string) ([]byte, error) {
memcachedItem, err := s.c.Get(key)
if errors.Is(err, memcache.ErrCacheMiss) {
return nil, ErrCacheItemNotFound
}
if err != nil {
return nil, err
}
return memcachedItem.Value, nil
}
// Delete delete a key from the cache
func (s *memcachedStorage) Delete(ctx context.Context, key string) error {
return s.c.Delete(key)
+23 -6
View File
@@ -93,26 +93,43 @@ func (s *redisStorage) Set(ctx context.Context, key string, val interface{}, exp
if err != nil {
return err
}
status := s.c.Set(ctx, key, string(value), expires)
return s.SetByteArray(ctx, key, value, expires)
}
// Set sets value to a given key
func (s *redisStorage) SetByteArray(ctx context.Context, key string, data []byte, expires time.Duration) error {
status := s.c.Set(ctx, key, data, expires)
return status.Err()
}
// Get gets value by given key in session.
func (s *redisStorage) Get(ctx context.Context, key string) (interface{}, error) {
v := s.c.Get(ctx, key)
v, err := s.GetByteArray(ctx, key)
if err.Error() == "EOF" {
return nil, ErrCacheItemNotFound
}
if err != nil {
return nil, err
}
item := &cachedItem{}
err := s.codec.Decode(ctx, []byte(v.Val()), item)
err = s.codec.Decode(ctx, v, item)
if err == nil {
return item.Val, nil
}
if err.Error() == "EOF" {
return nil, ErrCacheItemNotFound
}
return nil, err
}
// GetByteArray returns the value as byte array
func (s *redisStorage) GetByteArray(ctx context.Context, key string) ([]byte, error) {
return s.c.Get(ctx, key).Bytes()
}
// Delete delete a key from session.
func (s *redisStorage) Delete(ctx context.Context, key string) error {
cmd := s.c.Del(ctx, key)
+22
View File
@@ -61,6 +61,12 @@ type CacheStorage interface {
// Set sets an object into the cache. if `expire` is set to zero it will default to 24h
Set(ctx context.Context, key string, value interface{}, expire time.Duration) error
// GetByteArray gets the cache value as an byte array
GetByteArray(ctx context.Context, key string) ([]byte, error)
// SetByteArray saves the value as an byte array. if `expire` is set to zero it will default to 24h
SetByteArray(ctx context.Context, key string, value []byte, expire time.Duration) error
// Delete object from cache
Delete(ctx context.Context, key string) error
}
@@ -78,6 +84,16 @@ func (ds *RemoteCache) Get(ctx context.Context, key string) (interface{}, error)
return ds.client.Get(ctx, key)
}
// GetByteArray returns the cached value as an byte array
func (ds *RemoteCache) GetByteArray(ctx context.Context, key string) ([]byte, error) {
return ds.client.GetByteArray(ctx, key)
}
// SetByteArray stored the byte array in the cache
func (ds *RemoteCache) SetByteArray(ctx context.Context, key string, value []byte, expire time.Duration) error {
return ds.client.SetByteArray(ctx, key, value, expire)
}
// Set sets an object into the cache. if `expire` is set to zero it will default to 24h
func (ds *RemoteCache) Set(ctx context.Context, key string, value interface{}, expire time.Duration) error {
if expire == 0 {
@@ -186,9 +202,15 @@ type prefixCacheStorage struct {
func (pcs *prefixCacheStorage) Get(ctx context.Context, key string) (interface{}, error) {
return pcs.cache.Get(ctx, pcs.prefix+key)
}
func (pcs *prefixCacheStorage) GetByteArray(ctx context.Context, key string) ([]byte, error) {
return pcs.cache.GetByteArray(ctx, pcs.prefix+key)
}
func (pcs *prefixCacheStorage) Set(ctx context.Context, key string, value interface{}, expire time.Duration) error {
return pcs.cache.Set(ctx, pcs.prefix+key, value, expire)
}
func (pcs *prefixCacheStorage) SetByteArray(ctx context.Context, key string, value []byte, expire time.Duration) error {
return pcs.cache.SetByteArray(ctx, pcs.prefix+key, value, expire)
}
func (pcs *prefixCacheStorage) Delete(ctx context.Context, key string) error {
return pcs.cache.Delete(ctx, pcs.prefix+key)
}