Commit 889f059e authored by Marc Gravell's avatar Marc Gravell

Merge branch 'master' into pipelines (also: make RCS happy with the merged code)

# Conflicts:
#	StackExchange.Redis/StackExchange/Redis/Interfaces/IServer.cs
#	StackExchange.Redis/StackExchange/Redis/RedisServer.cs
parents 2777240f 7ec50486
...@@ -79,6 +79,20 @@ public void SentinelMasterTest() ...@@ -79,6 +79,20 @@ public void SentinelMasterTest()
} }
} }
[Fact]
public void SentinelSentinelsTest()
{
var sentinels = Server.SentinelSentinels("mymaster");
Assert.True(sentinels[0].ToDictionary().ContainsKey("name"));
foreach (var config in sentinels)
{
foreach (var kvp in config)
{
Writer.WriteLine("{0}:{1}", kvp.Key, kvp.Value);
}
}
}
[Fact] [Fact]
public void SentinelMastersTest() public void SentinelMastersTest()
{ {
......
...@@ -715,6 +715,22 @@ public partial interface IServer : IRedis ...@@ -715,6 +715,22 @@ public partial interface IServer : IRedis
/// <remarks>https://redis.io/topics/sentinel</remarks> /// <remarks>https://redis.io/topics/sentinel</remarks>
Task SentinelFailoverAsync(string serviceName, CommandFlags flags = CommandFlags.None); Task SentinelFailoverAsync(string serviceName, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Show a list of sentinels for a master, and their state.
/// </summary>
/// <param name="serviceName">The sentinel service name.</param>
/// <param name="flags">The command flags to use.</param>
/// <remarks>https://redis.io/topics/sentinel</remarks>
KeyValuePair<string, string>[][] SentinelSentinels(string serviceName, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Show a list of sentinels for a master, and their state.
/// </summary>
/// <param name="serviceName">The sentinel service name.</param>
/// <param name="flags">The command flags to use.</param>
/// <remarks>https://redis.io/topics/sentinel</remarks>
Task<KeyValuePair<string, string>[][]> SentinelSentinelsAsync(string serviceName, CommandFlags flags = CommandFlags.None);
#endregion #endregion
} }
......
...@@ -90,6 +90,7 @@ public static readonly RedisValue ...@@ -90,6 +90,7 @@ public static readonly RedisValue
GETMASTERADDRBYNAME = "GET-MASTER-ADDR-BY-NAME", GETMASTERADDRBYNAME = "GET-MASTER-ADDR-BY-NAME",
// RESET = "RESET", // RESET = "RESET",
FAILOVER = "FAILOVER", FAILOVER = "FAILOVER",
SENTINELS = "SENTINELS",
// Sentinel Literals as of 2.8.4 // Sentinel Literals as of 2.8.4
MONITOR = "MONITOR", MONITOR = "MONITOR",
......
...@@ -824,6 +824,20 @@ public Task SentinelFailoverAsync(string serviceName, CommandFlags flags = Comma ...@@ -824,6 +824,20 @@ public Task SentinelFailoverAsync(string serviceName, CommandFlags flags = Comma
return ExecuteAsync(msg, ResultProcessor.SentinelArrayOfArrays); return ExecuteAsync(msg, ResultProcessor.SentinelArrayOfArrays);
} }
public KeyValuePair<string, string>[][] SentinelSentinels(string serviceName, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.SENTINELS, (RedisValue)serviceName);
return ExecuteSync(msg, ResultProcessor.SentinelArrayOfArrays);
}
public Task<KeyValuePair<string, string>[][]> SentinelSentinelsAsync(string serviceName, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(-1, flags, RedisCommand.SENTINEL, RedisLiterals.SENTINELS, (RedisValue)serviceName);
return ExecuteAsync(msg, ResultProcessor.SentinelArrayOfArrays);
}
#endregion
public RedisResult Execute(string command, params object[] args) => Execute(command, args, CommandFlags.None); public RedisResult Execute(string command, params object[] args) => Execute(command, args, CommandFlags.None);
public RedisResult Execute(string command, ICollection<object> args, CommandFlags flags = CommandFlags.None) public RedisResult Execute(string command, ICollection<object> args, CommandFlags flags = CommandFlags.None)
...@@ -840,8 +854,6 @@ public Task<RedisResult> ExecuteAsync(string command, ICollection<object> args, ...@@ -840,8 +854,6 @@ public Task<RedisResult> ExecuteAsync(string command, ICollection<object> args,
return ExecuteAsync(msg, ResultProcessor.ScriptResult); return ExecuteAsync(msg, ResultProcessor.ScriptResult);
} }
#endregion
/// <summary> /// <summary>
/// For testing only /// For testing only
/// </summary> /// </summary>
......
...@@ -164,7 +164,7 @@ protected override void WriteImpl(PhysicalConnection physical) ...@@ -164,7 +164,7 @@ protected override void WriteImpl(PhysicalConnection physical)
public override int ArgCount => Wrapped.ArgCount; public override int ArgCount => Wrapped.ArgCount;
public override string CommandAndKey => Wrapped.CommandAndKey; public override string CommandAndKey => Wrapped.CommandAndKey;
public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
=> Wrapped.GetHashSlot(serverSelectionStrategy); => Wrapped.GetHashSlot(serverSelectionStrategy);
} }
private class QueuedProcessor : ResultProcessor<bool> private class QueuedProcessor : ResultProcessor<bool>
...@@ -249,7 +249,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -249,7 +249,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
// PART 1: issue the pre-conditions // PART 1: issue the pre-conditions
if (!IsAborted && conditions.Length != 0) if (!IsAborted && conditions.Length != 0)
{ {
sb.AppendLine($"issuing conditions..."); sb.AppendLine("issuing conditions...");
int cmdCount = 0; int cmdCount = 0;
for (int i = 0; i < conditions.Length; i++) for (int i = 0; i < conditions.Length; i++)
{ {
...@@ -263,15 +263,15 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -263,15 +263,15 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{ {
msg.SetNoRedirect(); // need to keep them in the current context only msg.SetNoRedirect(); // need to keep them in the current context only
yield return msg; yield return msg;
sb.AppendLine($"issuing {msg.CommandAndKey}"); sb.Append("issuing ").AppendLine(msg.CommandAndKey);
cmdCount++; cmdCount++;
} }
} }
sb.AppendLine($"issued {conditions.Length} conditions ({cmdCount} commands)"); sb.Append("issued ").Append(conditions.Length).Append(" conditions (").Append(cmdCount).AppendLine(" commands)");
if (!explicitCheckForQueued && lastBox != null) if (!explicitCheckForQueued && lastBox != null)
{ {
sb.AppendLine($"checking conditions in the *early* path"); sb.AppendLine("checking conditions in the *early* path");
// need to get those sent ASAP; if they are stuck in the buffers, we die // need to get those sent ASAP; if they are stuck in the buffers, we die
multiplexer.Trace("Flushing and waiting for precondition responses"); multiplexer.Trace("Flushing and waiting for precondition responses");
connection.FlushAsync().Wait(); connection.FlushAsync().Wait();
...@@ -280,14 +280,14 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -280,14 +280,14 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
if (!AreAllConditionsSatisfied(multiplexer)) if (!AreAllConditionsSatisfied(multiplexer))
command = RedisCommand.UNWATCH; // somebody isn't happy command = RedisCommand.UNWATCH; // somebody isn't happy
sb.AppendLine($"after condition check, we are {command}"); sb.Append("after condition check, we are ").Append(command).AppendLine();
} }
else else
{ // timeout running pre-conditions { // timeout running pre-conditions
multiplexer.Trace("Timeout checking preconditions"); multiplexer.Trace("Timeout checking preconditions");
command = RedisCommand.UNWATCH; command = RedisCommand.UNWATCH;
sb.AppendLine($"timeout waiting for conditions, we are {command}"); sb.Append("timeout waiting for conditions, we are ").Append(command).AppendLine();
} }
Monitor.Exit(lastBox); Monitor.Exit(lastBox);
lastBox = null; lastBox = null;
...@@ -299,7 +299,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -299,7 +299,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{ {
multiplexer.Trace("Begining transaction"); multiplexer.Trace("Begining transaction");
yield return Message.Create(-1, CommandFlags.None, RedisCommand.MULTI); yield return Message.Create(-1, CommandFlags.None, RedisCommand.MULTI);
sb.AppendLine($"issued MULTI"); sb.AppendLine("issued MULTI");
} }
// PART 3: issue the commands // PART 3: issue the commands
...@@ -321,13 +321,13 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -321,13 +321,13 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
} }
} }
yield return op; yield return op;
sb.AppendLine($"issued {op.CommandAndKey}"); sb.Append("issued ").AppendLine(op.CommandAndKey);
} }
sb.AppendLine($"issued {InnerOperations.Length} operations"); sb.Append("issued ").Append(InnerOperations.Length).AppendLine(" operations");
if (explicitCheckForQueued && lastBox != null) if (explicitCheckForQueued && lastBox != null)
{ {
sb.AppendLine($"checking conditions in the *late* path"); sb.AppendLine("checking conditions in the *late* path");
multiplexer.Trace("Flushing and waiting for precondition+queued responses"); multiplexer.Trace("Flushing and waiting for precondition+queued responses");
connection.FlushAsync().Wait(); // make sure they get sent, so we can check for QUEUED (and the pre-conditions if necessary) connection.FlushAsync().Wait(); // make sure they get sent, so we can check for QUEUED (and the pre-conditions if necessary)
...@@ -344,20 +344,20 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -344,20 +344,20 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
if (!op.WasQueued) if (!op.WasQueued)
{ {
multiplexer.Trace("Aborting: operation was not queued: " + op.Command); multiplexer.Trace("Aborting: operation was not queued: " + op.Command);
sb.AppendLine($"command was not issued: {op.CommandAndKey}"); sb.Append("command was not issued: ").AppendLine(op.CommandAndKey);
command = RedisCommand.DISCARD; command = RedisCommand.DISCARD;
break; break;
} }
} }
} }
multiplexer.Trace("Confirmed: QUEUED x " + InnerOperations.Length); multiplexer.Trace("Confirmed: QUEUED x " + InnerOperations.Length);
sb.AppendLine($"after condition check, we are {command}"); sb.Append("after condition check, we are ").Append(command).AppendLine();
} }
else else
{ {
multiplexer.Trace("Aborting: timeout checking queued messages"); multiplexer.Trace("Aborting: timeout checking queued messages");
command = RedisCommand.DISCARD; command = RedisCommand.DISCARD;
sb.AppendLine($"timeout waiting for conditions, we are {command}"); sb.Append("timeout waiting for conditions, we are ").Append(command).AppendLine();
} }
Monitor.Exit(lastBox); Monitor.Exit(lastBox);
lastBox = null; lastBox = null;
...@@ -370,7 +370,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -370,7 +370,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
} }
if (IsAborted) if (IsAborted)
{ {
sb.AppendLine($"aborting {InnerOperations.Length} wrapped commands..."); sb.Append("aborting ").Append(InnerOperations.Length).AppendLine(" wrapped commands...");
connection.Trace("Aborting: canceling wrapped messages"); connection.Trace("Aborting: canceling wrapped messages");
foreach (var op in InnerOperations) foreach (var op in InnerOperations)
{ {
...@@ -379,7 +379,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection) ...@@ -379,7 +379,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
} }
} }
connection.Trace("End of transaction: " + Command); connection.Trace("End of transaction: " + Command);
sb.AppendLine($"issuing {Command}"); sb.Append("issuing ").Append(Command).AppendLine();
yield return this; // acts as either an EXEC or an UNWATCH, depending on "aborted" yield return this; // acts as either an EXEC or an UNWATCH, depending on "aborted"
} }
finally finally
......
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