[v9.2.x] Chore: Remote cache key prefix (#59838) (#59877)

Chore: Remote cache key prefix (#59838)

* attempt to implement a remote cache key prefix

* add a test for the prefix store

* oh, linter

(cherry picked from commit 3978502d83)
This commit is contained in:
Serge Zaitsev
2022-12-06 15:16:36 +01:00
committed by GitHub
parent efc69a08fa
commit b221e8cac9
5 changed files with 64 additions and 11 deletions
+3
View File
@@ -139,6 +139,9 @@ type = database
# memcache: 127.0.0.1:11211
connstr =
# prefix prepended to all the keys in the remote cache
prefix =
#################################### Data proxy ###########################
[dataproxy]
+3
View File
@@ -145,6 +145,9 @@
# memcache: 127.0.0.1:11211
;connstr =
# prefix prepended to all the keys in the remote cache
; prefix =
#################################### Data proxy ###########################
[dataproxy]
+30 -11
View File
@@ -97,20 +97,24 @@ func (ds *RemoteCache) Run(ctx context.Context) error {
return ctx.Err()
}
func createClient(opts *setting.RemoteCacheOptions, sqlstore *sqlstore.SQLStore) (CacheStorage, error) {
if opts.Name == redisCacheType {
return newRedisStorage(opts)
func createClient(opts *setting.RemoteCacheOptions, sqlstore *sqlstore.SQLStore) (cache CacheStorage, err error) {
switch opts.Name {
case redisCacheType:
cache, err = newRedisStorage(opts)
case memcachedCacheType:
cache = newMemcachedStorage(opts)
case databaseCacheType:
cache = newDatabaseCache(sqlstore)
default:
return nil, ErrInvalidCacheType
}
if opts.Name == memcachedCacheType {
return newMemcachedStorage(opts), nil
if err != nil {
return cache, err
}
if opts.Name == databaseCacheType {
return newDatabaseCache(sqlstore), nil
if opts.Prefix != "" {
cache = &prefixCacheStorage{cache: cache, prefix: opts.Prefix}
}
return nil, ErrInvalidCacheType
return cache, nil
}
// Register records a type, identified by a value for that type, under its
@@ -137,3 +141,18 @@ func decodeGob(data []byte, out *cachedItem) error {
buf := bytes.NewBuffer(data)
return gob.NewDecoder(buf).Decode(&out)
}
type prefixCacheStorage struct {
cache CacheStorage
prefix string
}
func (pcs *prefixCacheStorage) Get(ctx context.Context, key string) (interface{}, error) {
return pcs.cache.Get(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) Delete(ctx context.Context, key string) error {
return pcs.cache.Delete(ctx, pcs.prefix+key)
}
+25
View File
@@ -5,6 +5,7 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert"
@@ -87,3 +88,27 @@ func canNotFetchExpiredItems(t *testing.T, client CacheStorage) {
_, err = client.Get(context.Background(), "key1")
assert.Equal(t, err, ErrCacheItemNotFound)
}
func TestCachePrefix(t *testing.T) {
db := sqlstore.InitTestDB(t)
cache := &databaseCache{
SQLStore: db,
log: log.New("remotecache.database"),
}
prefixCache := &prefixCacheStorage{cache: cache, prefix: "test/"}
// Set a value (with a prefix)
err := prefixCache.Set(context.Background(), "foo", "bar", time.Hour)
require.NoError(t, err)
// Get a value (with a prefix)
v, err := prefixCache.Get(context.Background(), "foo")
require.NoError(t, err)
require.Equal(t, "bar", v)
// Get a value directly from the underlying cache, ensure the prefix is in the key
v, err = cache.Get(context.Background(), "test/foo")
require.NoError(t, err)
require.Equal(t, "bar", v)
// Get a value directly from the underlying cache without a prefix, should not be there
_, err = cache.Get(context.Background(), "foo")
require.Error(t, err)
}
+3
View File
@@ -1072,10 +1072,12 @@ func (cfg *Cfg) Load(args CommandLineArgs) error {
cacheServer := iniFile.Section("remote_cache")
dbName := valueAsString(cacheServer, "type", "database")
connStr := valueAsString(cacheServer, "connstr", "")
prefix := valueAsString(cacheServer, "prefix", "")
cfg.RemoteCacheOptions = &RemoteCacheOptions{
Name: dbName,
ConnStr: connStr,
Prefix: prefix,
}
geomapSection := iniFile.Section("geomap")
@@ -1111,6 +1113,7 @@ func valueAsString(section *ini.Section, keyName string, defaultValue string) st
type RemoteCacheOptions struct {
Name string
ConnStr string
Prefix string
}
func (cfg *Cfg) readLDAPConfig() {