Skip to content

Commit 49f24a2

Browse files
NickCravermgravell
andauthored
Sentinel: Several break fixes (#1402)
* fix naming of SentinelGetSentinelAddressesAsync * tyop * Sentinel: don't use async over sync with .Result Co-authored-by: mgravell <[email protected]>
1 parent 46be338 commit 49f24a2

File tree

4 files changed

+38
-64
lines changed

4 files changed

+38
-64
lines changed

src/StackExchange.Redis/ConnectionMultiplexer.cs

Lines changed: 16 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,53 +2303,16 @@ internal void OnManagedConnectionFailed(object sender, ConnectionFailedEventArgs
23032303
{
23042304
SwitchMaster(e.EndPoint, connection);
23052305
}, null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1));
2306-
2307-
//connection.sentinelMasterReconnectTimer.AutoReset = true;
2308-
2309-
//connection.sentinelMasterReconnectTimer.Start();
23102306
}
23112307
}
23122308

2313-
internal EndPoint GetConfiguredMasterForService(string serviceName, int timeoutmillis = -1)
2314-
{
2315-
Task<EndPoint>[] sentinelMasters = GetServerSnapshot().ToArray()
2316-
.Where(s => s.ServerType == ServerType.Sentinel)
2317-
.Select(s => GetServer(s.EndPoint).SentinelGetMasterAddressByNameAsync(serviceName))
2318-
.ToArray();
2319-
2320-
Task<Task<EndPoint>> firstCompleteRequest = WaitFirstNonNullIgnoreErrorsAsync(sentinelMasters);
2321-
if (!firstCompleteRequest.Wait(timeoutmillis))
2322-
throw new TimeoutException("Timeout resolving master for service");
2323-
if (firstCompleteRequest.Result?.Result == null)
2324-
throw new Exception("Unable to determine master");
2325-
2326-
return firstCompleteRequest.Result.Result;
2327-
}
2328-
2329-
private static async Task<Task<T>> WaitFirstNonNullIgnoreErrorsAsync<T>(Task<T>[] tasks)
2330-
{
2331-
if (tasks == null) throw new ArgumentNullException("tasks");
2332-
if (tasks.Length == 0) return null;
2333-
var typeNullable = (Nullable.GetUnderlyingType(typeof(T)) != null);
2334-
var taskList = tasks.Cast<Task>().ToList();
2335-
2336-
try
2337-
{
2338-
while (taskList.Count > 0)
2339-
{
2340-
var allTasksAwaitingAny = Task.WhenAny(taskList).ObserveErrors();
2341-
var result = await allTasksAwaitingAny.ForAwait();
2342-
taskList.Remove((Task<T>)result);
2343-
if (((Task<T>)result).IsFaulted) continue;
2344-
if ((!typeNullable) || ((Task<T>)result).Result != null)
2345-
return (Task<T>)result;
2346-
}
2347-
}
2348-
catch
2349-
{ }
2350-
2351-
return null;
2352-
}
2309+
internal EndPoint GetConfiguredMasterForService(string serviceName) =>
2310+
GetServerSnapshot()
2311+
.ToArray()
2312+
.Where(s => s.ServerType == ServerType.Sentinel)
2313+
.AsParallel()
2314+
.Select(s => GetServer(s.EndPoint).SentinelGetMasterAddressByName(serviceName))
2315+
.First(r => r != null);
23532316

23542317
internal EndPoint currentSentinelMasterEndPoint;
23552318

@@ -2419,26 +2382,22 @@ private T Retry<T>(int times, int interval, Func<T> func, string message)
24192382
throw new NullReferenceException(message);
24202383
}
24212384

2422-
internal void UpdateSentinelAddressList(string serviceName, int timeoutmillis = 500)
2385+
internal void UpdateSentinelAddressList(string serviceName)
24232386
{
2424-
Task<EndPoint[]>[] sentinels = GetServerSnapshot().ToArray()
2425-
.Where(s => s.ServerType == ServerType.Sentinel)
2426-
.Select(s => GetServer(s.EndPoint).SentinelGetSentinelAddresses(serviceName))
2427-
.ToArray();
2428-
2429-
Task<Task<EndPoint[]>> firstCompleteRequest = WaitFirstNonNullIgnoreErrorsAsync(sentinels);
2387+
var firstCompleteRequest = GetServerSnapshot()
2388+
.ToArray()
2389+
.Where(s => s.ServerType == ServerType.Sentinel)
2390+
.AsParallel()
2391+
.Select(s => GetServer(s.EndPoint).SentinelGetSentinelAddresses(serviceName))
2392+
.First(r => r != null);
24302393

24312394
// Ignore errors, as having an updated sentinel list is
24322395
// not essential
2433-
if (firstCompleteRequest.Result?.Result == null)
2434-
return;
2435-
if (!firstCompleteRequest.Wait(timeoutmillis))
2436-
return;
2437-
if (firstCompleteRequest.Result.Result == null)
2396+
if (firstCompleteRequest == null)
24382397
return;
24392398

24402399
bool hasNew = false;
2441-
foreach (EndPoint newSentinel in firstCompleteRequest.Result.Result.Where(x => !RawConfig.EndPoints.Contains(x)))
2400+
foreach (EndPoint newSentinel in firstCompleteRequest.Where(x => !RawConfig.EndPoints.Contains(x)))
24422401
{
24432402
hasNew = true;
24442403
RawConfig.EndPoints.Add(newSentinel);

src/StackExchange.Redis/Interfaces/IServer.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,10 +756,19 @@ public partial interface IServer : IRedis
756756
/// Returns the ip and port numbers of all known Sentinels
757757
/// for the given service name.
758758
/// </summary>
759-
/// <param name="serviveName">the sentinel service name</param>
759+
/// <param name="serviceName">the sentinel service name</param>
760760
/// <param name="flags"></param>
761761
/// <returns>a list of the sentinel ips and ports</returns>
762-
Task<EndPoint[]> SentinelGetSentinelAddresses(string serviveName, CommandFlags flags = CommandFlags.None);
762+
EndPoint[] SentinelGetSentinelAddresses(string serviceName, CommandFlags flags = CommandFlags.None);
763+
764+
/// <summary>
765+
/// Returns the ip and port numbers of all known Sentinels
766+
/// for the given service name.
767+
/// </summary>
768+
/// <param name="serviceName">the sentinel service name</param>
769+
/// <param name="flags"></param>
770+
/// <returns>a list of the sentinel ips and ports</returns>
771+
Task<EndPoint[]> SentinelGetSentinelAddressesAsync(string serviceName, CommandFlags flags = CommandFlags.None);
763772

764773
/// <summary>
765774
/// Show the state and info of the specified master.

src/StackExchange.Redis/RedisServer.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,10 +807,16 @@ public Task<EndPoint> SentinelGetMasterAddressByNameAsync(string serviceName, Co
807807
return ExecuteAsync(msg, ResultProcessor.SentinelMasterEndpoint);
808808
}
809809

810-
public Task<EndPoint[]> SentinelGetSentinelAddresses(string serviceName, CommandFlags flags = CommandFlags.None)
810+
public EndPoint[] SentinelGetSentinelAddresses(string serviceName, CommandFlags flags = CommandFlags.None)
811811
{
812812
var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.SENTINELS, (RedisValue)serviceName);
813-
return ExecuteAsync(msg, ResultProcessor.SentinelAddressesEndPoints);
813+
return ExecuteSync(msg, ResultProcessor.SentinelAddressesEndPoints);
814+
}
815+
816+
public Task<EndPoint[]> SentinelGetSentinelAddressesAsync(string serviceName, CommandFlags flags = CommandFlags.None)
817+
{
818+
var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.SENTINELS, (RedisValue)serviceName);
819+
return ExecuteAsync(msg, ResultProcessor.SentinelAddressesEndPoints);
814820
}
815821

816822
public KeyValuePair<string, string>[] SentinelMaster(string serviceName, CommandFlags flags = CommandFlags.None)

tests/StackExchange.Redis.Tests/Sentinel.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,15 +562,15 @@ await UntilCondition(TimeSpan.FromSeconds(20), () =>
562562
[Fact]
563563
public async Task SentinelGetSentinelAddressesTest()
564564
{
565-
var addresses = await SentinelServerA.SentinelGetSentinelAddresses(ServiceName).ForAwait();
565+
var addresses = await SentinelServerA.SentinelGetSentinelAddressesAsync(ServiceName).ForAwait();
566566
Assert.Contains(SentinelServerB.EndPoint, addresses);
567567
Assert.Contains(SentinelServerC.EndPoint, addresses);
568568

569-
addresses = await SentinelServerB.SentinelGetSentinelAddresses(ServiceName).ForAwait();
569+
addresses = await SentinelServerB.SentinelGetSentinelAddressesAsync(ServiceName).ForAwait();
570570
Assert.Contains(SentinelServerA.EndPoint, addresses);
571571
Assert.Contains(SentinelServerC.EndPoint, addresses);
572572

573-
addresses = await SentinelServerC.SentinelGetSentinelAddresses(ServiceName).ForAwait();
573+
addresses = await SentinelServerC.SentinelGetSentinelAddressesAsync(ServiceName).ForAwait();
574574
Assert.Contains(SentinelServerA.EndPoint, addresses);
575575
Assert.Contains(SentinelServerB.EndPoint, addresses);
576576
}

0 commit comments

Comments
 (0)