feat(storage): implement Redis distributed lock and cache invalidation broadcasting

- Add Redis distributed lock in Execute of MigrationHandler to prevent concurrent storage migrations.
- Define storage:config_invalidation Redis pub/sub channel to broadcast cache invalidation events.
- Implement background pub/sub listener on all nodes to evict config memory cache concurrently.
- Add integration tests for distributed locking and invalidation propagation using miniredis.
This commit is contained in:
ryan
2026-06-13 15:21:32 +08:00
parent acd430836f
commit 26a1e71a27
6 changed files with 187 additions and 5 deletions
@@ -14,6 +14,7 @@ import (
"os"
"strings"
"sync/atomic"
"time"
"github.com/Rain-kl/Wavelet/internal/db"
"github.com/Rain-kl/Wavelet/internal/model"
@@ -67,6 +68,18 @@ func (h *MigrationHandler) ValidatePayload(payload []byte) ([]byte, error) {
// Execute migrates all unique active-storage objects to the pending backend.
func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*task.TaskResult, error) {
if db.Redis != nil {
lockKey := db.PrefixedKey("lock:storage:migrate")
ok, err := db.Redis.SetNX(ctx, lockKey, "locked", time.Hour).Result()
if err != nil {
return nil, fmt.Errorf("acquire migration lock: %w", err)
}
if !ok {
return nil, errors.New("另一个存储迁移任务正在运行中")
}
defer db.Redis.Del(ctx, lockKey)
}
active, err := storage.LoadConfig(ctx)
if err != nil {
return nil, fmt.Errorf("load active storage config: %w", err)