diff --git a/temporal/internal/driver/redisv9/keyvalue.go b/temporal/internal/driver/redisv9/keyvalue.go index ead0d6f6..bc6f0937 100644 --- a/temporal/internal/driver/redisv9/keyvalue.go +++ b/temporal/internal/driver/redisv9/keyvalue.go @@ -214,23 +214,28 @@ func (r *RedisV9) DeleteScanMatch(ctx context.Context, pattern string) (int64, e func (r *RedisV9) deleteScanMatchSingleNode(ctx context.Context, client redis.Cmdable, pattern string) (int64, error) { var deleted, cursor uint64 var err error + for { + var keys []string + keys, cursor, err = client.Scan(ctx, cursor, pattern, 0).Result() + if err != nil { + break + } - var keys []string - keys, _, err = client.Scan(ctx, cursor, pattern, 0).Result() - if err != nil { - return int64(deleted), err - } + if len(keys) > 0 { + del, err := client.Del(ctx, keys...).Result() + if err != nil { + break + } - if len(keys) > 0 { - del, err := client.Del(ctx, keys...).Result() - if err != nil { - return int64(deleted), err + deleted += uint64(del) } - deleted += uint64(del) + if cursor == 0 { + break + } } - return int64(deleted), nil + return int64(deleted), err } // Keys returns all keys matching the given pattern diff --git a/temporal/keyvalue/keyvalue_test.go b/temporal/keyvalue/keyvalue_test.go index 0e2c7d3a..c9e58cfd 100644 --- a/temporal/keyvalue/keyvalue_test.go +++ b/temporal/keyvalue/keyvalue_test.go @@ -666,6 +666,30 @@ func TestKeyValue_DeleteScanMatch(t *testing.T) { expectedDeleted: 2, expectedErr: nil, }, + { + name: "many_keys_pattern", + setup: func(db KeyValue) { + prefix := "cache-ec9d1ec9e4d64a9869d6596e27a79c11" + for i := 0; i < 100; i++ { + key := fmt.Sprintf("%s-%d", prefix, i) + err := db.Set(context.Background(), key, fmt.Sprintf("value%d", i), 0) + if err != nil { + t.Fatalf("Set() error = %v", err) + } + } + // Adding some non-matching keys + for i := 0; i < 10; i++ { + key := fmt.Sprintf("other-key-%d", i) + err := db.Set(context.Background(), key, fmt.Sprintf("value%d", i), 0) + if err != nil { + t.Fatalf("Set() error = %v", err) + } + } + }, + pattern: "cache-ec9d1ec9e4d64a9869d6596e27a79c11*", + expectedDeleted: 100, + expectedErr: nil, + }, { name: "non_matching_pattern", pattern: "key*", @@ -710,6 +734,13 @@ func TestKeyValue_DeleteScanMatch(t *testing.T) { deleted, err := kv.DeleteScanMatch(ctx, tc.pattern) assert.Equal(t, tc.expectedErr, err) assert.Equal(t, tc.expectedDeleted, deleted) + + // additional verification to ensure keys are actually deleted + if tc.pattern != "" && tc.expectedErr == nil { + keys, err := kv.Keys(ctx, tc.pattern) + assert.Nil(t, err) + assert.Empty(t, keys, "Keys should be empty after DeleteScanMatch") + } }) } }