Commit e898ec45 authored by Nick Craver's avatar Nick Craver

Fix SentinelGetMasterAddressByName

This is interesting, and may explain some other hangs. Previously, arr was null, and the .Length call in the MultiBulk case was throwing a null ref. This doesn't throw externally through, it just runs forever. While there's a timeout guard against this on the ExecuteSync path, there's not on ExecuteAsync. This is easy to reproduce for example add this at the top of the result processor:

if (result.Type == ResultType.MultiBulk) throw new Exception("Woops");

...and we'll only see timeouts on sync and forever runs on async. I left this code in (commented) for an easy repro case.

/cc @mgravell
parent 77c8af09
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
......@@ -62,6 +63,13 @@ public void SentinelGetMasterAddressByNameNegativeTest()
Assert.Null(endpoint);
}
[Fact]
public async Task SentinelGetMasterAddressByNameAsyncNegativeTest()
{
var endpoint = await Server.SentinelGetMasterAddressByNameAsync("FakeServiceName");
Assert.Null(endpoint);
}
[Fact]
public void SentinelMasterTest()
{
......
......@@ -1414,13 +1414,18 @@ private sealed class SentinelGetMasterAddressByNameProcessor : ResultProcessor<E
{
protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
{
// To repro timeout fail:
// if (result.Type == ResultType.MultiBulk) throw new Exception("Woops");
switch (result.Type)
{
case ResultType.MultiBulk:
var arr = result.GetItemsAsValues();
int port;
if (arr.Length == 2 && int.TryParse(arr[1], out port))
if (result.IsNull)
{
return true;
}
else if (arr.Length == 2 && int.TryParse(arr[1], out var port))
{
SetResult(message, Format.ParseEndPoint(arr[0], port));
return true;
......
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