[cache] add app-wide prefix

This commit is contained in:
Aleksandr Soloshenko 2025-09-11 11:41:40 +07:00 committed by Aleksandr
parent f24a9ee2d4
commit 43da4f56da
5 changed files with 33 additions and 11 deletions

View File

@ -8,6 +8,10 @@ import (
"github.com/android-sms-gateway/server/pkg/cache"
)
const (
keyPrefix = "sms-gateway:"
)
type Cache = cache.Cache
type Factory interface {
@ -52,5 +56,5 @@ func NewFactory(config Config) (Factory, error) {
// New implements Factory.
func (f *factory) New(name string) (cache.Cache, error) {
return f.new(name)
return f.new(keyPrefix + name)
}

7
pkg/cache/memory.go vendored
View File

@ -110,12 +110,13 @@ func (m *memoryCache) SetOrFail(_ context.Context, key string, value string, opt
m.mux.Lock()
defer m.mux.Unlock()
if _, ok := m.items[key]; ok {
return ErrKeyExists
if item, ok := m.items[key]; ok {
if !item.isExpired(time.Now()) {
return ErrKeyExists
}
}
m.items[key] = m.newItem(value, opts...)
return nil
}

View File

@ -241,7 +241,7 @@ func TestMemoryCache_RapidOperations(t *testing.T) {
} else {
key := "rapid-key-" + strconv.Itoa(i-1)
_, err := c.Get(ctx, key)
if err != nil && err != cache.ErrKeyNotFound {
if err != nil {
t.Errorf("Get failed: %v", err)
}
}

View File

@ -189,10 +189,10 @@ func TestMemoryCache_GCStress(t *testing.T) {
runtime.GC()
// Verify cache operations still work
for j := 0; j < 100; j++ {
for j := range 100 {
key := "gc-key-" + strconv.Itoa(j)
_, err := c.Get(ctx, key)
if err != nil && err != cache.ErrKeyNotFound {
if err != nil {
t.Errorf("Get failed during GC stress test: %v", err)
}
}

25
pkg/cache/redis.go vendored
View File

@ -21,6 +21,16 @@ if value then
else
return false
end
`
hgetallAndDeleteScript = `
local items = redis.call('HGETALL', KEYS[1])
if #items > 0 then
for i = 1, #items, 2 do
redis.call('HDEL', KEYS[1], items[i])
end
end
return items
`
)
@ -62,17 +72,24 @@ func (r *redisCache) Delete(ctx context.Context, key string) error {
// Drain implements Cache.
func (r *redisCache) Drain(ctx context.Context) (map[string]string, error) {
items, err := r.client.HGetAll(ctx, r.key).Result()
res, err := r.client.Eval(ctx, hgetallAndDeleteScript, []string{r.key}).Result()
if err != nil {
return nil, fmt.Errorf("can't drain cache: %w", err)
}
if err := r.client.Del(ctx, r.key).Err(); err != nil {
return nil, fmt.Errorf("can't cleanup cache: %w", err)
arr, ok := res.([]any)
if !ok || len(arr) == 0 {
return map[string]string{}, nil
}
return items, nil
out := make(map[string]string, len(arr)/2)
for i := 0; i < len(arr); i += 2 {
f, _ := arr[i].(string)
v, _ := arr[i+1].(string)
out[f] = v
}
return out, nil
}
// Get implements Cache.