Skip to content

Commit ac76c77

Browse files
committed
- fix cluster routing
- many operations were working by following `-MOVED`, which is inefficient (and causes a topology fetch for every miss, due to panic) - change tests to disable `-MOVED` redirection; in tests, failure is preferable
1 parent fe78b2c commit ac76c77

File tree

8 files changed

+82
-53
lines changed

8 files changed

+82
-53
lines changed

src/NRedisStack/Auxiliary.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,26 +61,31 @@ internal static void SetInfoInPipeline(this IDatabase db)
6161
}
6262
}
6363

64+
#if DEBUG
65+
private const CommandFlags Flags = CommandFlags.NoRedirect; // disable redirect, so we spot -MOVED in tests
66+
#else
67+
private const CommandFlags Flags = CommandFlags.None;
68+
#endif
6469
public static RedisResult Execute(this IDatabase db, SerializedCommand command)
6570
{
6671
db.SetInfoInPipeline();
67-
return db.Execute(command.Command, command.Args);
72+
return db.Execute(command.Command, command.Args, flags: Flags);
6873
}
6974

7075
internal static RedisResult Execute(this IServer server, int? db, SerializedCommand command)
7176
{
72-
return server.Execute(db, command.Command, command.Args);
77+
return server.Execute(db, command.Command, command.Args, flags: Flags);
7378
}
7479

7580
public static async Task<RedisResult> ExecuteAsync(this IDatabaseAsync db, SerializedCommand command)
7681
{
7782
((IDatabase)db).SetInfoInPipeline();
78-
return await db.ExecuteAsync(command.Command, command.Args);
83+
return await db.ExecuteAsync(command.Command, command.Args, flags: Flags);
7984
}
8085

8186
internal static async Task<RedisResult> ExecuteAsync(this IServer server, int? db, SerializedCommand command)
8287
{
83-
return await server.ExecuteAsync(db, command.Command, command.Args);
88+
return await server.ExecuteAsync(db, command.Command, command.Args, flags: Flags);
8489
}
8590

8691
public static List<RedisResult> ExecuteBroadcast(this IDatabase db, string command)

src/NRedisStack/Json/JsonCommandBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ public static SerializedCommand Type(RedisKey key, string? path = null)
7171
public static SerializedCommand DebugMemory(string key, string? path = null)
7272
{
7373
return (path != null)
74-
? new(JSON.DEBUG, JSON.MEMORY, key, path)
75-
: new SerializedCommand(JSON.DEBUG, JSON.MEMORY, key);
74+
? new(JSON.DEBUG, JSON.MEMORY, (RedisKey)key, path)
75+
: new SerializedCommand(JSON.DEBUG, JSON.MEMORY, (RedisKey)key);
7676
}
7777

7878
public static SerializedCommand ArrAppend(RedisKey key, string? path = null, params object[] values)

src/NRedisStack/Search/SearchCommandBuilder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,20 +196,20 @@ public static SerializedCommand SpellCheck(string indexName, string query, FTSpe
196196

197197
public static SerializedCommand SugAdd(string key, string str, double score, bool increment = false, string? payload = null)
198198
{
199-
var args = new List<object> { key, str, score };
199+
var args = new List<object> { (RedisKey)key, str, score };
200200
if (increment) { args.Add(SearchArgs.INCR); }
201201
if (payload != null) { args.Add(SearchArgs.PAYLOAD); args.Add(payload); }
202202
return new(FT.SUGADD, args);
203203
}
204204

205205
public static SerializedCommand SugDel(string key, string str)
206206
{
207-
return new(FT.SUGDEL, key, str);
207+
return new(FT.SUGDEL, (RedisKey)key, str);
208208
}
209209

210210
public static SerializedCommand SugGet(string key, string prefix, bool fuzzy = false, bool withScores = false, bool withPayloads = false, int? max = null)
211211
{
212-
var args = new List<object> { key, prefix };
212+
var args = new List<object> { (RedisKey)key, prefix };
213213
if (fuzzy) { args.Add(SearchArgs.FUZZY); }
214214
if (withScores) { args.Add(SearchArgs.WITHSCORES); }
215215
if (withPayloads) { args.Add(SearchArgs.WITHPAYLOADS); }
@@ -219,7 +219,7 @@ public static SerializedCommand SugGet(string key, string prefix, bool fuzzy = f
219219

220220
public static SerializedCommand SugLen(string key)
221221
{
222-
return new(FT.SUGLEN, key);
222+
return new(FT.SUGLEN, (RedisKey)key);
223223
}
224224

225225
public static SerializedCommand SynDump(string indexName)

src/NRedisStack/Tdigest/TdigestCommandBuilder.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ public static class TdigestCommandBuilder
88
{
99
public static SerializedCommand Add(RedisKey key, params double[] values)
1010
{
11-
if (values.Length < 0) throw new ArgumentOutOfRangeException(nameof(values));
12-
var args = new string[values.Length + 1];
13-
args[0] = key.ToString();
11+
var args = new object[values.Length + 1];
12+
args[0] = key;
1413
for (int i = 0; i < values.Length; i++)
1514
{
16-
args[i + 1] = values[i].ToString();
15+
args[i + 1] = values[i];
1716
}
1817

1918
return new(TDIGEST.ADD, args);

src/NRedisStack/TimeSeries/DataTypes/TSParameters.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using NRedisStack.DataTypes;
22
using NRedisStack.Literals.Enums;
3+
using StackExchange.Redis;
34

45
namespace NRedisStack;
56

@@ -17,7 +18,7 @@ internal TsBaseParams(IList<object> parameters)
1718
this.parameters = parameters;
1819
}
1920

20-
internal object[] ToArray(string key)
21+
internal object[] ToArray(RedisKey key)
2122
{
2223
parameters.Insert(0, key);
2324
return parameters.ToArray();

tests/NRedisStack.Tests/Search/SearchTests.cs

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2933,10 +2933,12 @@ public async Task TestQueryParamsWithParams_DefaultDialectAsync(string endpointI
29332933

29342934
readonly string key = "SugTestKey";
29352935

2936-
[Fact]
2937-
public void TestAddAndGetSuggestion()
2936+
[SkippableTheory]
2937+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
2938+
public void TestAddAndGetSuggestion(string endpointId)
29382939
{
2939-
IDatabase db = GetCleanDatabase();
2940+
SkipClusterPre8(endpointId);
2941+
IDatabase db = GetCleanDatabase(endpointId);
29402942
var ft = db.FT();
29412943

29422944
string suggestion = "ANOTHER_WORD";
@@ -2955,9 +2957,11 @@ public void TestAddAndGetSuggestion()
29552957
Assert.Single(ft.SugGet(key, noMatch.Substring(1, 6), true, max: 5));
29562958
}
29572959

2958-
[Fact]
2959-
public async Task TestAddAndGetSuggestionAsync()
2960+
[SkippableTheory]
2961+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
2962+
public async Task TestAddAndGetSuggestionAsync(string endpointId)
29602963
{
2964+
SkipClusterPre8(endpointId);
29612965
IDatabase db = GetCleanDatabase();
29622966
var ft = db.FT();
29632967

@@ -2977,10 +2981,12 @@ public async Task TestAddAndGetSuggestionAsync()
29772981
Assert.Single(await ft.SugGetAsync(key, noMatch.Substring(1, 6), true, max: 5));
29782982
}
29792983

2980-
[Fact]
2981-
public void AddSuggestionIncrAndGetSuggestionFuzzy()
2984+
[SkippableTheory]
2985+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
2986+
public void AddSuggestionIncrAndGetSuggestionFuzzy(string endpointId)
29822987
{
2983-
IDatabase db = GetCleanDatabase();
2988+
SkipClusterPre8(endpointId);
2989+
IDatabase db = GetCleanDatabase(endpointId);
29842990
var ft = db.FT();
29852991
string suggestion = "TOPIC OF WORDS";
29862992

@@ -2991,10 +2997,12 @@ public void AddSuggestionIncrAndGetSuggestionFuzzy()
29912997
Assert.Equal(suggestion, ft.SugGet(key, suggestion.Substring(0, 3))[0]);
29922998
}
29932999

2994-
[Fact]
2995-
public async Task AddSuggestionIncrAndGetSuggestionFuzzyAsync()
3000+
[SkippableTheory]
3001+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
3002+
public async Task AddSuggestionIncrAndGetSuggestionFuzzyAsync(string endpointId)
29963003
{
2997-
IDatabase db = GetCleanDatabase();
3004+
SkipClusterPre8(endpointId);
3005+
IDatabase db = GetCleanDatabase(endpointId);
29983006
var ft = db.FT();
29993007
string suggestion = "TOPIC OF WORDS";
30003008

@@ -3005,10 +3013,12 @@ public async Task AddSuggestionIncrAndGetSuggestionFuzzyAsync()
30053013
Assert.Equal(suggestion, (await ft.SugGetAsync(key, suggestion.Substring(0, 3)))[0]);
30063014
}
30073015

3008-
[Fact]
3009-
public void getSuggestionScores()
3016+
[SkippableTheory]
3017+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
3018+
public void getSuggestionScores(string endpointId)
30103019
{
3011-
IDatabase db = GetCleanDatabase();
3020+
SkipClusterPre8(endpointId);
3021+
IDatabase db = GetCleanDatabase(endpointId);
30123022
var ft = db.FT();
30133023
ft.SugAdd(key, "COUNT_ME TOO", 1);
30143024
ft.SugAdd(key, "COUNT", 1);
@@ -3025,10 +3035,12 @@ public void getSuggestionScores()
30253035
}
30263036
}
30273037

3028-
[Fact]
3029-
public async Task getSuggestionScoresAsync()
3038+
[SkippableTheory]
3039+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
3040+
public async Task getSuggestionScoresAsync(string endpointId)
30303041
{
3031-
IDatabase db = GetCleanDatabase();
3042+
SkipClusterPre8(endpointId);
3043+
IDatabase db = GetCleanDatabase(endpointId);
30323044
var ft = db.FT();
30333045
await ft.SugAddAsync(key, "COUNT_ME TOO", 1);
30343046
await ft.SugAddAsync(key, "COUNT", 1);
@@ -3045,10 +3057,12 @@ public async Task getSuggestionScoresAsync()
30453057
}
30463058
}
30473059

3048-
[Fact]
3049-
public void getSuggestionMax()
3060+
[SkippableTheory]
3061+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
3062+
public void getSuggestionMax(string endpointId)
30503063
{
3051-
IDatabase db = GetCleanDatabase();
3064+
SkipClusterPre8(endpointId);
3065+
IDatabase db = GetCleanDatabase(endpointId);
30523066
var ft = db.FT();
30533067
ft.SugAdd(key, "COUNT_ME TOO", 1);
30543068
ft.SugAdd(key, "COUNT", 1);
@@ -3059,10 +3073,12 @@ public void getSuggestionMax()
30593073
Assert.Equal(2, ft.SugGetWithScores(key, "COU", true, max: 2).Count);
30603074
}
30613075

3062-
[Fact]
3063-
public async Task getSuggestionMaxAsync()
3076+
[SkippableTheory]
3077+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
3078+
public async Task getSuggestionMaxAsync(string endpointId)
30643079
{
3065-
IDatabase db = GetCleanDatabase();
3080+
SkipClusterPre8(endpointId);
3081+
IDatabase db = GetCleanDatabase(endpointId);
30663082
var ft = db.FT();
30673083
await ft.SugAddAsync(key, "COUNT_ME TOO", 1);
30683084
await ft.SugAddAsync(key, "COUNT", 1);
@@ -3073,32 +3089,38 @@ public async Task getSuggestionMaxAsync()
30733089
Assert.Equal(2, (await ft.SugGetWithScoresAsync(key, "COU", true, max: 2)).Count);
30743090
}
30753091

3076-
[Fact]
3077-
public void getSuggestionNoHit()
3092+
[SkippableTheory]
3093+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
3094+
public void getSuggestionNoHit(string endpointId)
30783095
{
3079-
IDatabase db = GetCleanDatabase();
3096+
SkipClusterPre8(endpointId);
3097+
IDatabase db = GetCleanDatabase(endpointId);
30803098
var ft = db.FT();
30813099
ft.SugAdd(key, "NO WORD", 0.4);
30823100

30833101
Assert.Empty(ft.SugGetWithScores(key, "DIF"));
30843102
Assert.Empty(ft.SugGet(key, "DIF"));
30853103
}
30863104

3087-
[Fact]
3088-
public async Task getSuggestionNoHitAsync()
3105+
[SkippableTheory]
3106+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
3107+
public async Task GetSuggestionNoHitAsync(string endpointId)
30893108
{
3090-
IDatabase db = GetCleanDatabase();
3109+
SkipClusterPre8(endpointId);
3110+
IDatabase db = GetCleanDatabase(endpointId);
30913111
var ft = db.FT();
30923112
await ft.SugAddAsync(key, "NO WORD", 0.4);
30933113

30943114
Assert.Empty((await ft.SugGetWithScoresAsync(key, "DIF")));
30953115
Assert.Empty((await ft.SugGetAsync(key, "DIF")));
30963116
}
30973117

3098-
[Fact]
3099-
public void getSuggestionLengthAndDeleteSuggestion()
3118+
[SkippableTheory]
3119+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
3120+
public void GetSuggestionLengthAndDeleteSuggestion(string endpointId)
31003121
{
3101-
IDatabase db = GetCleanDatabase();
3122+
SkipClusterPre8(endpointId);
3123+
IDatabase db = GetCleanDatabase(endpointId);
31023124
var ft = db.FT();
31033125
ft.SugAdd(key, "TOPIC OF WORDS", 1, increment: true);
31043126
ft.SugAdd(key, "ANOTHER ENTRY", 1, increment: true);
@@ -3117,10 +3139,12 @@ public void getSuggestionLengthAndDeleteSuggestion()
31173139
Assert.Equal(2L, ft.SugLen(key));
31183140
}
31193141

3120-
[Fact]
3121-
public async Task getSuggestionLengthAndDeleteSuggestionAsync()
3142+
[SkippableTheory]
3143+
[MemberData(nameof(EndpointsFixture.Env.AllEnvironments), MemberType = typeof(EndpointsFixture.Env))]
3144+
public async Task getSuggestionLengthAndDeleteSuggestionAsync(string endpointId)
31223145
{
3123-
IDatabase db = GetCleanDatabase();
3146+
SkipClusterPre8(endpointId);
3147+
IDatabase db = GetCleanDatabase(endpointId);
31243148
var ft = db.FT();
31253149
await ft.SugAddAsync(key, "TOPIC OF WORDS", 1, increment: true);
31263150
await ft.SugAddAsync(key, "ANOTHER ENTRY", 1, increment: true);

tests/NRedisStack.Tests/TimeSeries/TestAPI/TestCreate.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public void TestParamsBuilder()
137137
.AddUncompressed(true).build();
138138

139139
var command = TimeSeriesCommandsBuilder.Create(key, parameters);
140-
var expectedArgs = new object[] { key, "RETENTION", 5000L, "CHUNK_SIZE", 1000L, "LABELS", "key", "value", "UNCOMPRESSED", "DUPLICATE_POLICY", "FIRST", "IGNORE", 11L, 12L };
140+
var expectedArgs = new object[] { (RedisKey)key, "RETENTION", 5000L, "CHUNK_SIZE", 1000L, "LABELS", "key", "value", "UNCOMPRESSED", "DUPLICATE_POLICY", "FIRST", "IGNORE", 11L, 12L };
141141
Assert.Equal(expectedArgs, command.Args);
142142

143143
parameters = new TsCreateParamsBuilder()
@@ -149,7 +149,7 @@ public void TestParamsBuilder()
149149
.AddUncompressed(false).build();
150150

151151
command = TimeSeriesCommandsBuilder.Create(key, parameters);
152-
expectedArgs = [key, "RETENTION", 5000L, "CHUNK_SIZE", 1000L, "LABELS", "key", "value", "COMPRESSED", "DUPLICATE_POLICY", "FIRST", "IGNORE", 11L, 12L
152+
expectedArgs = [(RedisKey)key, "RETENTION", 5000L, "CHUNK_SIZE", 1000L, "LABELS", "key", "value", "COMPRESSED", "DUPLICATE_POLICY", "FIRST", "IGNORE", 11L, 12L
153153
];
154154
Assert.Equal(expectedArgs, command.Args);
155155
}

tests/NRedisStack.Tests/TimeSeries/TestAPI/TimeSeriesHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class TimeSeriesHelper
77
{
88
public static RedisResult getInfo(IDatabase db, string key, out int j, out int k)
99
{
10-
var cmd = new SerializedCommand("TS.INFO", key);
10+
var cmd = new SerializedCommand("TS.INFO", (RedisKey)key);
1111
RedisResult info = db.Execute(cmd);
1212

1313
j = -1;

0 commit comments

Comments
 (0)