mirror of
https://github.com/lukaszraczylo/graphql-monitoring-proxy.git
synced 2026-11-04 08:04:10 +00:00
fix(redis): namespace cache keys when no prefix is set
With an empty prefix, Clear deleted every key in the Redis database, including keys of other applications. Cache keys now start with gmp: by default. Existing cache entries become unreachable after the upgrade and expire by TTL.
This commit is contained in:
Vendored
+9
-1
@@ -83,7 +83,15 @@ type RedisClientConfig struct {
|
||||
// entry.
|
||||
const defaultTTL = 60 * time.Second
|
||||
|
||||
// DefaultKeyPrefix namespaces cache keys when no prefix is configured, so Clear
|
||||
// and CountQueries never touch keys of other applications on a shared Redis.
|
||||
const DefaultKeyPrefix = "gmp:"
|
||||
|
||||
func New(redisClientConfig *RedisClientConfig) (*RedisConfig, error) {
|
||||
prefix := redisClientConfig.Prefix
|
||||
if prefix == "" {
|
||||
prefix = DefaultKeyPrefix
|
||||
}
|
||||
c := &RedisConfig{
|
||||
client: redis.NewClient(&redis.Options{
|
||||
Addr: redisClientConfig.RedisServer,
|
||||
@@ -91,7 +99,7 @@ func New(redisClientConfig *RedisClientConfig) (*RedisConfig, error) {
|
||||
DB: redisClientConfig.RedisDB,
|
||||
}),
|
||||
ctx: context.Background(),
|
||||
prefix: redisClientConfig.Prefix,
|
||||
prefix: prefix,
|
||||
builderPool: &sync.Pool{
|
||||
New: func() any {
|
||||
return &strings.Builder{}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package libpack_cache_redis
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/alicebob/miniredis/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// Pins theorems/Theorems/RedisClear.lean: with no configured prefix, Clear must still spare foreign keys.
|
||||
func TestClear_DefaultPrefixSparesForeignKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
s, err := miniredis.Run()
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(s.Close)
|
||||
|
||||
require.NoError(t, s.Set("other-app:session", "keep"))
|
||||
|
||||
c, err := New(&RedisClientConfig{RedisServer: s.Addr()})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.Set("q1", []byte("v"), 0))
|
||||
|
||||
require.NoError(t, c.Clear())
|
||||
|
||||
assert.True(t, s.Exists("other-app:session"), "foreign key was deleted")
|
||||
_, found, err := c.Get("q1")
|
||||
require.NoError(t, err)
|
||||
assert.False(t, found, "own key must be cleared")
|
||||
}
|
||||
Vendored
+4
-4
@@ -131,11 +131,11 @@ func (suite *RedisConfigSuite) TestGetKeys() {
|
||||
err = suite.redisConfig.Set("otherkey", []byte("othervalue"), ttl)
|
||||
assert.NoError(suite.T(), err)
|
||||
|
||||
keys, _ := suite.redisConfig.client.Keys(suite.redisConfig.ctx, "testkey*").Result()
|
||||
expectedKeys := []string{"testkey1", "testkey2"}
|
||||
keys, _ := suite.redisConfig.client.Keys(suite.redisConfig.ctx, DefaultKeyPrefix+"testkey*").Result()
|
||||
expectedKeys := []string{DefaultKeyPrefix + "testkey1", DefaultKeyPrefix + "testkey2"}
|
||||
assert.ElementsMatch(suite.T(), expectedKeys, keys)
|
||||
|
||||
suite.redisConfig.client.Del(suite.redisConfig.ctx, "testkey1", "testkey2", "otherkey")
|
||||
suite.redisConfig.client.Del(suite.redisConfig.ctx, DefaultKeyPrefix+"testkey1", DefaultKeyPrefix+"testkey2", DefaultKeyPrefix+"otherkey")
|
||||
}
|
||||
|
||||
func (suite *RedisConfigSuite) TestGetKeysCount() {
|
||||
@@ -154,5 +154,5 @@ func (suite *RedisConfigSuite) TestGetKeysCount() {
|
||||
assert.NoError(suite.T(), err)
|
||||
assert.Equal(suite.T(), int64(3), count3)
|
||||
|
||||
suite.redisConfig.client.Del(suite.redisConfig.ctx, "testkey1", "testkey2", "otherkey")
|
||||
suite.redisConfig.client.Del(suite.redisConfig.ctx, DefaultKeyPrefix+"testkey1", DefaultKeyPrefix+"testkey2", DefaultKeyPrefix+"otherkey")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user