Chore: Remote cache key prefix (#59838)

* attempt to implement a remote cache key prefix

* add a test for the prefix store

* oh, linter
This commit is contained in:
Serge Zaitsev 2022-12-06 13:20:49 +01:00 committed by GitHub
parent 932349b5ab
commit 3978502d83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 11 deletions

View File

@ -162,6 +162,9 @@ type = database
# memcache: 127.0.0.1:11211
connstr =
# prefix prepended to all the keys in the remote cache
prefix =
#################################### Data proxy ###########################
[dataproxy]

View File

@ -169,6 +169,9 @@
# memcache: 127.0.0.1:11211
;connstr =
# prefix prepended to all the keys in the remote cache
; prefix =
#################################### Data proxy ###########################
[dataproxy]

View File

@ -97,20 +97,24 @@ func (ds *RemoteCache) Run(ctx context.Context) error {
return ctx.Err()
}
func createClient(opts *setting.RemoteCacheOptions, sqlstore db.DB) (CacheStorage, error) {
if opts.Name == redisCacheType {
return newRedisStorage(opts)
func createClient(opts *setting.RemoteCacheOptions, sqlstore db.DB) (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)
}

View File

@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/setting"
)
@ -88,3 +89,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 := db.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)
}

View File

@ -1120,10 +1120,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")
@ -1159,6 +1161,7 @@ func valueAsString(section *ini.Section, keyName string, defaultValue string) st
type RemoteCacheOptions struct {
Name string
ConnStr string
Prefix string
}
func (cfg *Cfg) readLDAPConfig() {