Skip to content

Commit

Permalink
- add explicit connection failure type
Browse files Browse the repository at this point in the history
- burn the connection on failure
- add initial metrics
  • Loading branch information
mgravell committed Jun 20, 2024
1 parent 75ae891 commit 3a9d8c9
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 7 deletions.
6 changes: 5 additions & 1 deletion src/StackExchange.Redis/Enums/ConnectionFailureType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public enum ConnectionFailureType
/// <summary>
/// It has not been possible to create an initial connection to the redis server(s).
/// </summary>
UnableToConnect
UnableToConnect,
/// <summary>
/// High-integrity mode was enabled, and a failure was detected
/// </summary>
ResponseIntegrityFailure,
}
}
12 changes: 8 additions & 4 deletions src/StackExchange.Redis/PhysicalConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1705,7 +1705,10 @@ private void MatchResult(in RawResult result)
if (_awaitingToken is not null && (msg = Interlocked.Exchange(ref _awaitingToken, null)) is not null)
{
_readStatus = ReadStatus.ResponseSequenceCheck;
ProcessHighIntegrityResponseToken(msg, in result, BridgeCouldBeNull);
if (!ProcessHighIntegrityResponseToken(msg, in result, BridgeCouldBeNull))
{
RecordConnectionFailed(ConnectionFailureType.ResponseIntegrityFailure, origin: nameof(ReadStatus.ResponseSequenceCheck));
}
return;
}

Expand Down Expand Up @@ -1745,7 +1748,7 @@ private void MatchResult(in RawResult result)
_readStatus = ReadStatus.MatchResultComplete;
_activeMessage = null;

static void ProcessHighIntegrityResponseToken(Message message, in RawResult result, PhysicalBridge? bridge)
static bool ProcessHighIntegrityResponseToken(Message message, in RawResult result, PhysicalBridge? bridge)
{
bool isValid = false;
if (result.Resp2TypeBulkString == ResultType.BulkString)
Expand All @@ -1762,20 +1765,21 @@ static void ProcessHighIntegrityResponseToken(Message message, in RawResult resu
{
Span<byte> span = stackalloc byte[4];
payload.CopyTo(span);
interpreted = BinaryPrimitives.ReadUInt32LittleEndian(payload.First.Span);
interpreted = BinaryPrimitives.ReadUInt32LittleEndian(span);
}
isValid = interpreted == message.HighIntegrityToken;
}
}
if (isValid)
{
message.Complete();
return true;
}
else
{
message.SetExceptionAndComplete(new InvalidOperationException("High-integrity mode detected possible protocol de-sync"), bridge);
return false;
}

}

static bool TryGetPubSubPayload(in RawResult value, out RedisValue parsed, bool allowArraySingleton = true)
Expand Down
1 change: 1 addition & 0 deletions src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ StackExchange.Redis.ConnectionFailureType.ProtocolFailure = 4 -> StackExchange.R
StackExchange.Redis.ConnectionFailureType.SocketClosed = 6 -> StackExchange.Redis.ConnectionFailureType
StackExchange.Redis.ConnectionFailureType.SocketFailure = 2 -> StackExchange.Redis.ConnectionFailureType
StackExchange.Redis.ConnectionFailureType.UnableToConnect = 9 -> StackExchange.Redis.ConnectionFailureType
StackExchange.Redis.ConnectionFailureType.ResponseIntegrityFailure = 10 -> StackExchange.Redis.ConnectionFailureType
StackExchange.Redis.ConnectionFailureType.UnableToResolvePhysicalConnection = 1 -> StackExchange.Redis.ConnectionFailureType
StackExchange.Redis.ConnectionMultiplexer
StackExchange.Redis.ConnectionMultiplexer.ClientName.get -> string!
Expand Down
2 changes: 1 addition & 1 deletion src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@

#nullable enable
13 changes: 12 additions & 1 deletion tests/ConsoleTest/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,24 @@
stopwatch.Start();

var options = ConfigurationOptions.Parse("localhost");
#if !SEREDIS_BASELINE
options.HighIntegrity = false; // as needed
Console.WriteLine($"{nameof(options.HighIntegrity)}: {options.HighIntegrity}");
#endif

//options.SocketManager = SocketManager.ThreadPool;
var connection = ConnectionMultiplexer.Connect(options);
connection.ConnectionFailed += Connection_ConnectionFailed;

void Connection_ConnectionFailed(object? sender, ConnectionFailedEventArgs e)
{
Console.Error.WriteLine($"CONNECTION FAILED: {e.ConnectionType}, {e.FailureType}, {e.Exception}");
}

var startTime = DateTime.UtcNow;
var startCpuUsage = Process.GetCurrentProcess().TotalProcessorTime;

var scenario = args?.Length > 0 ? args[0] : "parallel";
var scenario = args?.Length > 0 ? args[0] : "mass-insert";

switch (scenario)
{
Expand Down
1 change: 1 addition & 0 deletions tests/ConsoleTestBaseline/ConsoleTestBaseline.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<DefineConstants>$(DefineConstants);SEREDIS_BASELINE</DefineConstants>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 3a9d8c9

Please sign in to comment.