mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-07 08:06:37 +08:00
perf(config): add Otter RAM cache layer for system configs
Introduce pkg/cache/ram on top of existing Redis/DB config reads. GetByKey now checks local RAM before Redis. Unified invalidation clears RAM and Redis hash fields on admin writes, with pub/sub for multi-node RAM eviction. Add tests and wire create/update/migrator write paths.
This commit is contained in:
Vendored
+1
-5
@@ -129,9 +129,5 @@ func saveOrUpdateConfig(ctx context.Context, key string, value string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Sync config value in Redis cache
|
||||
if db.Redis != nil {
|
||||
_ = db.HSetJSON(ctx, model.SystemConfigRedisHashKey, key, &sc)
|
||||
}
|
||||
return nil
|
||||
return model.InvalidateSystemConfigCache(ctx, key)
|
||||
}
|
||||
|
||||
@@ -87,16 +87,16 @@ func CreateSystemConfig(c *gin.Context) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := db.HSetJSON(c.Request.Context(), model.SystemConfigRedisHashKey, req.Key, &config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, response.Err(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if err := model.InvalidateSystemConfigCache(c.Request.Context(), req.Key); err != nil {
|
||||
logger.WarnF(c.Request.Context(), "清理系统配置缓存失败: %v", err)
|
||||
}
|
||||
|
||||
if err := model.InvalidateVisibleSystemConfigsCache(c.Request.Context()); err != nil {
|
||||
logger.WarnF(c.Request.Context(), "清理公共配置列表缓存失败: %v", err)
|
||||
}
|
||||
@@ -233,10 +233,6 @@ func UpdateSystemConfig(c *gin.Context) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := db.HSetJSON(c.Request.Context(), model.SystemConfigRedisHashKey, key, &config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resolveStorageMigrationTasksOnDirectDriverUpdate(
|
||||
c.Request.Context(),
|
||||
tx,
|
||||
@@ -287,6 +283,10 @@ func resolveStorageMigrationTasksOnDirectDriverUpdate(
|
||||
}
|
||||
|
||||
func invalidateCachesAfterConfigUpdate(ctx context.Context, key string) {
|
||||
if err := model.InvalidateSystemConfigCache(ctx, key); err != nil {
|
||||
logger.WarnF(ctx, "清理系统配置缓存失败: %v", err)
|
||||
}
|
||||
|
||||
if key == model.ConfigKeyStorageConfig {
|
||||
upload.ResetAccessCaches()
|
||||
upload.PublishAccessCacheInvalidation(ctx)
|
||||
|
||||
@@ -83,17 +83,25 @@ func TestCreateSystemConfig(t *testing.T) {
|
||||
t.Fatalf("failed to find system config in DB: %v", err)
|
||||
}
|
||||
|
||||
// Verify Redis Cache
|
||||
var redisConfig model.SystemConfig
|
||||
err = db.HGetJSON(context.Background(), model.SystemConfigRedisHashKey, "custom_key", &redisConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to find system config in Redis: %v", err)
|
||||
// Verify caches are invalidated after create and repopulate on read
|
||||
_, err = db.Redis.HGet(
|
||||
context.Background(),
|
||||
db.PrefixedKey(model.SystemConfigRedisHashKey),
|
||||
"custom_key",
|
||||
).Result()
|
||||
if err == nil {
|
||||
t.Fatal("expected redis cache miss immediately after create")
|
||||
}
|
||||
if redisConfig.Value != "custom_value" {
|
||||
t.Errorf("CreateSystemConfig(custom_key).Value = %q, want %q", redisConfig.Value, "custom_value")
|
||||
|
||||
var loaded model.SystemConfig
|
||||
if err := loaded.GetByKey(context.Background(), "custom_key"); err != nil {
|
||||
t.Fatalf("GetByKey(custom_key) error = %v", err)
|
||||
}
|
||||
if redisConfig.Visibility != model.ConfigVisibilityVisible {
|
||||
t.Errorf("CreateSystemConfig(custom_key).Visibility = %d, want %d", redisConfig.Visibility, model.ConfigVisibilityVisible)
|
||||
if loaded.Value != "custom_value" {
|
||||
t.Errorf("GetByKey(custom_key).Value = %q, want %q", loaded.Value, "custom_value")
|
||||
}
|
||||
if loaded.Visibility != model.ConfigVisibilityVisible {
|
||||
t.Errorf("GetByKey(custom_key).Visibility = %d, want %d", loaded.Visibility, model.ConfigVisibilityVisible)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -234,14 +242,25 @@ func TestUpdateSystemConfig(t *testing.T) {
|
||||
t.Errorf("database values not updated: %+v", cfg)
|
||||
}
|
||||
|
||||
// Verify Redis
|
||||
var redisConfig model.SystemConfig
|
||||
_ = db.HGetJSON(context.Background(), model.SystemConfigRedisHashKey, model.ConfigKeySiteName, &redisConfig)
|
||||
if redisConfig.Value != "Super Site Name" {
|
||||
t.Errorf("redis cache value not updated, got '%s'", redisConfig.Value)
|
||||
// Verify caches are invalidated after update and repopulate on read
|
||||
_, err := db.Redis.HGet(
|
||||
context.Background(),
|
||||
db.PrefixedKey(model.SystemConfigRedisHashKey),
|
||||
model.ConfigKeySiteName,
|
||||
).Result()
|
||||
if err == nil {
|
||||
t.Fatal("expected redis cache miss immediately after update")
|
||||
}
|
||||
if redisConfig.Visibility != model.ConfigVisibilityHidden {
|
||||
t.Errorf("redis cache visibility = %d, want %d", redisConfig.Visibility, model.ConfigVisibilityHidden)
|
||||
|
||||
var loaded model.SystemConfig
|
||||
if err := loaded.GetByKey(context.Background(), model.ConfigKeySiteName); err != nil {
|
||||
t.Fatalf("GetByKey(site_name) error = %v", err)
|
||||
}
|
||||
if loaded.Value != "Super Site Name" {
|
||||
t.Errorf("GetByKey(site_name).Value = %q, want %q", loaded.Value, "Super Site Name")
|
||||
}
|
||||
if loaded.Visibility != model.ConfigVisibilityHidden {
|
||||
t.Errorf("GetByKey(site_name).Visibility = %d, want %d", loaded.Visibility, model.ConfigVisibilityHidden)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user