Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 717f55d

Browse files
committed
Send connect commands outside of managed buffer to prevent pollution with pending commands
1 parent 81c8a4f commit 717f55d

File tree

3 files changed

+64
-3
lines changed

3 files changed

+64
-3
lines changed

src/ServiceStack.Redis/RedisNativeClient_Utils.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,13 @@ private void Connect()
140140
Bstream = new BufferedStream(networkStream, 16 * 1024);
141141

142142
if (!string.IsNullOrEmpty(Password))
143-
SendExpectSuccess(Commands.Auth, Password.ToUtf8Bytes());
143+
SendUnmanagedExpectSuccess(Commands.Auth, Password.ToUtf8Bytes());
144144

145145
if (db != 0)
146-
SendExpectSuccess(Commands.Select, db.ToUtf8Bytes());
146+
SendUnmanagedExpectSuccess(Commands.Select, db.ToUtf8Bytes());
147147

148148
if (Client != null)
149-
SendExpectSuccess(Commands.Client, Commands.SetName, Client.ToUtf8Bytes());
149+
SendUnmanagedExpectSuccess(Commands.Client, Commands.SetName, Client.ToUtf8Bytes());
150150

151151
try
152152
{
@@ -370,6 +370,24 @@ protected void WriteCommandToSendBuffer(params byte[][] cmdWithBinaryArgs)
370370
WriteAllToSendBuffer(cmdWithBinaryArgs);
371371
}
372372

373+
/// <summary>
374+
/// Send command outside of managed Write Buffer
375+
/// </summary>
376+
/// <param name="cmdWithBinaryArgs"></param>
377+
protected void SendUnmanagedExpectSuccess(params byte[][] cmdWithBinaryArgs)
378+
{
379+
var bytes = GetCmdBytes('*', cmdWithBinaryArgs.Length);
380+
381+
foreach (var safeBinaryValue in cmdWithBinaryArgs)
382+
{
383+
bytes = bytes.Combine(GetCmdBytes('$', safeBinaryValue.Length), safeBinaryValue, endData);
384+
}
385+
386+
Bstream.Write(bytes, 0, bytes.Length);
387+
388+
ExpectSuccess();
389+
}
390+
373391
public void WriteAllToSendBuffer(params byte[][] cmdWithBinaryArgs)
374392
{
375393
WriteToSendBuffer(GetCmdBytes('*', cmdWithBinaryArgs.Length));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System.Linq;
2+
using NUnit.Framework;
3+
4+
namespace ServiceStack.Redis.Tests.Issues
5+
{
6+
public class AuthIssue
7+
{
8+
[Test]
9+
[Ignore("Requires password on master")]
10+
public void Does_retry_failed_commands_auth()
11+
{
12+
// -> Redis must have "requirepass testpassword" in config
13+
var connstr = "testpassword@localhost";
14+
RedisStats.Reset();
15+
16+
var redisCtrl = new RedisClient(connstr); //RedisConfig.DefaultHost
17+
redisCtrl.FlushAll();
18+
redisCtrl.SetClient("redisCtrl");
19+
20+
var redis = new RedisClient(connstr);
21+
redis.SetClient("redisRetry");
22+
23+
var clientInfo = redisCtrl.GetClientsInfo();
24+
var redisId = clientInfo.First(m => m["name"] == "redisRetry")["id"];
25+
Assert.That(redisId.Length, Is.GreaterThan(0));
26+
27+
Assert.That(redis.IncrementValue("retryCounter"), Is.EqualTo(1));
28+
29+
redis.OnBeforeFlush = () =>
30+
{
31+
redisCtrl.KillClients(withId: redisId);
32+
};
33+
34+
Assert.That(redis.IncrementValue("retryCounter"), Is.EqualTo(2));
35+
Assert.That(redis.Get<int>("retryCounter"), Is.EqualTo(2));
36+
37+
Assert.That(RedisStats.TotalRetryCount, Is.EqualTo(1));
38+
Assert.That(RedisStats.TotalRetrySuccess, Is.EqualTo(1));
39+
Assert.That(RedisStats.TotalRetryTimedout, Is.EqualTo(0));
40+
}
41+
}
42+
}

tests/ServiceStack.Redis.Tests/ServiceStack.Redis.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@
184184
<Compile Include="BasicRediscClientManagerTests.cs" />
185185
<Compile Include="ConfigTests.cs" />
186186
<Compile Include="CustomCommandTests.cs" />
187+
<Compile Include="Issues\AuthIssue.cs" />
187188
<Compile Include="LuaCachedScripts.cs" />
188189
<Compile Include="Examples\TestData.cs" />
189190
<Compile Include="Issues\RedisCharacterizationTests.cs" />

0 commit comments

Comments
 (0)