Commit b0637c6f authored by Marc Gravell's avatar Marc Gravell

fix null handling error

parent d1c358c5
......@@ -37,9 +37,12 @@ public void Exec()
keyExists = cache.KeyExists(key);
ttl = cache.KeyTimeToLive(key);
fullWait = cache.HashGetAsync(key, "full", flags: CommandFlags.None);
Assert.False(keyExists);
Assert.Null(ttl);
Assert.Null((string)fullWait.Result);
var r = fullWait.Result;
Assert.True(r.IsNull);
Assert.Null((string)r);
}
}
}
......
using System.Buffers;
using Xunit;
namespace StackExchange.Redis.Tests
{
public class RawResultTests
{
[Fact]
public void NullWorks()
{
var result = new RawResult(ResultType.BulkString, ReadOnlySequence<byte>.Empty, true);
Assert.Equal(ResultType.BulkString, result.Type);
Assert.True(result.IsNull);
var value = result.AsRedisValue();
Assert.True(value.IsNull);
string s = (string)value;
Assert.Null(s);
byte[] arr = (byte[])value;
Assert.Null(arr);
}
[Fact]
public void DefaultWorks()
{
var result = default(RawResult);
Assert.Equal(ResultType.None, result.Type);
Assert.True(result.IsNull);
var value = result.AsRedisValue();
Assert.True(value.IsNull);
var s = (string)value;
Assert.Null(s);
var arr = (byte[])value;
Assert.Null(arr);
}
[Fact]
public void NilWorks()
{
var result = RawResult.Nil;
Assert.Equal(ResultType.None, result.Type);
Assert.True(result.IsNull);
var value = result.AsRedisValue();
Assert.True(value.IsNull);
var s = (string)value;
Assert.Null(s);
var arr = (byte[])value;
Assert.Null(arr);
}
}
}
......@@ -8,6 +8,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
appveyor.yml = appveyor.yml
Directory.build.props = Directory.build.props
global.json = global.json
NuGet.Config = NuGet.Config
version.json = version.json
EndProjectSection
......@@ -66,6 +67,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Basic", "Basic", "{38BDEEED
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicTestBaseline", "BasicTestBaseline\BasicTestBaseline.csproj", "{8FDB623D-779B-4A84-BC6B-75106E41D8A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pipelines.Sockets.Unofficial", "..\Pipelines.Sockets.Unofficial\src\Pipelines.Sockets.Unofficial\Pipelines.Sockets.Unofficial.csproj", "{6BE847CC-5615-4C72-A304-3DB29725FC76}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestConsole", "TestConsole\TestConsole.csproj", "{651FDB97-9DE3-4BD9-9A05-827AF8F1A94A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -122,6 +127,22 @@ Global
{8FDB623D-779B-4A84-BC6B-75106E41D8A4}.Release|Any CPU.Build.0 = Release|Any CPU
{8FDB623D-779B-4A84-BC6B-75106E41D8A4}.Verbose|Any CPU.ActiveCfg = Release|Any CPU
{8FDB623D-779B-4A84-BC6B-75106E41D8A4}.Verbose|Any CPU.Build.0 = Release|Any CPU
{6BE847CC-5615-4C72-A304-3DB29725FC76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BE847CC-5615-4C72-A304-3DB29725FC76}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BE847CC-5615-4C72-A304-3DB29725FC76}.Log Output|Any CPU.ActiveCfg = Debug|Any CPU
{6BE847CC-5615-4C72-A304-3DB29725FC76}.Log Output|Any CPU.Build.0 = Debug|Any CPU
{6BE847CC-5615-4C72-A304-3DB29725FC76}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BE847CC-5615-4C72-A304-3DB29725FC76}.Release|Any CPU.Build.0 = Release|Any CPU
{6BE847CC-5615-4C72-A304-3DB29725FC76}.Verbose|Any CPU.ActiveCfg = Debug|Any CPU
{6BE847CC-5615-4C72-A304-3DB29725FC76}.Verbose|Any CPU.Build.0 = Debug|Any CPU
{651FDB97-9DE3-4BD9-9A05-827AF8F1A94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{651FDB97-9DE3-4BD9-9A05-827AF8F1A94A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{651FDB97-9DE3-4BD9-9A05-827AF8F1A94A}.Log Output|Any CPU.ActiveCfg = Debug|Any CPU
{651FDB97-9DE3-4BD9-9A05-827AF8F1A94A}.Log Output|Any CPU.Build.0 = Debug|Any CPU
{651FDB97-9DE3-4BD9-9A05-827AF8F1A94A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{651FDB97-9DE3-4BD9-9A05-827AF8F1A94A}.Release|Any CPU.Build.0 = Release|Any CPU
{651FDB97-9DE3-4BD9-9A05-827AF8F1A94A}.Verbose|Any CPU.ActiveCfg = Debug|Any CPU
{651FDB97-9DE3-4BD9-9A05-827AF8F1A94A}.Verbose|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
......@@ -16,7 +16,13 @@
<ItemGroup>
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
<PackageReference Include="System.IO.Pipelines" Version="$(CoreFxVersion)" />
<PackageReference Include="Pipelines.Sockets.Unofficial" Version="0.2.1-alpha.43" />
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="$(CoreFxVersion)" />
</ItemGroup>
<ItemGroup Condition="'$(Computername)'=='OCHO'">
<ProjectReference Include="..\..\Pipelines.Sockets.Unofficial\src\Pipelines.Sockets.Unofficial\Pipelines.Sockets.Unofficial.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(Computername)'!='OCHO'">
<PackageReference Include="Pipelines.Sockets.Unofficial" Version="0.2.1-alpha.45" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -1003,9 +1003,8 @@ void ISocketCallback.OnHeartbeat()
}
var buffer = readResult.Buffer;
var s = new RawResult(ResultType.BulkString, buffer, false).GetString().Replace("\r","\\r").Replace("\n","\\n");
int handled = ProcessBuffer(ref buffer); // updates buffer.Start
allowSyncRead = handled != 0;
Multiplexer.Trace($"Processed {handled} messages", physicalName);
......
......@@ -7,15 +7,16 @@ namespace StackExchange.Redis
internal readonly struct RawResult
{
internal static readonly RawResult NullMultiBulk = new RawResult((RawResult[])null);
internal static readonly RawResult EmptyMultiBulk = new RawResult(new RawResult[0]);
internal static readonly RawResult Nil = new RawResult();
internal static readonly RawResult EmptyMultiBulk = new RawResult(Array.Empty<RawResult>());
internal static readonly RawResult Nil = default;
private readonly ReadOnlySequence<byte> _payload;
private readonly RawResult[] _subArray;
private readonly ResultType _type;
const ResultType NullResultTypeBit = unchecked((ResultType)(1 << 31));
const ResultType NonNullFlag = (ResultType)128;
public RawResult(ResultType resultType, ReadOnlySequence<byte> payload, bool isNull)
{
switch (resultType)
......@@ -28,7 +29,7 @@ public RawResult(ResultType resultType, ReadOnlySequence<byte> payload, bool isN
default:
throw new ArgumentOutOfRangeException(nameof(resultType));
}
if (isNull) resultType |= NullResultTypeBit;
if (!isNull) resultType |= NonNullFlag;
_type = resultType;
_payload = payload;
_subArray = default;
......@@ -37,19 +38,17 @@ public RawResult(ResultType resultType, ReadOnlySequence<byte> payload, bool isN
public RawResult(RawResult[] arr)
{
_type = ResultType.MultiBulk;
if (arr == null) _type |= NullResultTypeBit;
if (arr != null) _type |= NonNullFlag;
_payload = default;
_subArray = arr;
}
public bool HasValue => Type != ResultType.None;
public bool IsError => Type == ResultType.Error;
public ResultType Type => _type & ~NullResultTypeBit;
internal bool IsNull => (_type & NullResultTypeBit) != 0;
public ResultType Type => _type & ~NonNullFlag;
internal bool IsNull => (_type & NonNullFlag) == 0;
public bool HasValue => Type != ResultType.None;
public override string ToString()
{
if (IsNull) return "(null)";
......@@ -105,6 +104,7 @@ internal RedisKey AsRedisKey()
internal RedisValue AsRedisValue()
{
if (IsNull) return RedisValue.Null;
switch (Type)
{
case ResultType.Integer:
......
using System;
using System.Collections.Generic;
using System.IO;
using StackExchange.Redis;
class Program
{
static int Main()
{
var s = new StringWriter();
try
{
#if DEBUG
Pipelines.Sockets.Unofficial.DebugCounters.SetLog(Console.Out);
#endif
// it is sometimes hard to get the debugger to play nicely with benchmarkdotnet/xunit attached,
// so this is just a *trivial* exe
var config = new ConfigurationOptions
{
EndPoints = { "127.0.0.1" },
//TieBreaker = "",
//CommandMap = CommandMap.Create(new Dictionary<string, string>
//{
// ["SUBSCRIBE"] = null,
// ["PSUBSCRIBE"] = null,
//})
};
using (var conn = ConnectionMultiplexer.Connect(config, log: s))
{
Console.WriteLine("Connected");
var db = conn.GetDatabase();
db.StringSet("abc", "def");
var x = db.StringGet("abc");
Console.WriteLine(x);
//for (int i = 0; i < 10; i++)
//{
// Console.WriteLine($"Ping {i}");
// db.Ping();
//}
}
Console.WriteLine("Clean exit");
return 0;
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
return -1;
}
finally
{
Console.WriteLine();
Console.WriteLine(s);
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.1;net462</TargetFrameworks>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\StackExchange.Redis\StackExchange.Redis.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(Computername)'=='OCHO'">
<ProjectReference Include="..\..\Pipelines.Sockets.Unofficial\src\Pipelines.Sockets.Unofficial\Pipelines.Sockets.Unofficial.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(Computername)'!='OCHO'">
<PackageReference Include="Pipelines.Sockets.Unofficial" Version="0.2.1-alpha.45" />
</ItemGroup>
</Project>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment