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()
}
}
[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]
public void SentinelMastersTest()
{
......
......@@ -715,6 +715,22 @@ public partial interface IServer : IRedis
/// <remarks>https://redis.io/topics/sentinel</remarks>
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
}
......
......@@ -90,6 +90,7 @@ public static readonly RedisValue
GETMASTERADDRBYNAME = "GET-MASTER-ADDR-BY-NAME",
// RESET = "RESET",
FAILOVER = "FAILOVER",
SENTINELS = "SENTINELS",
// Sentinel Literals as of 2.8.4
MONITOR = "MONITOR",
......
......@@ -824,6 +824,20 @@ public Task SentinelFailoverAsync(string serviceName, CommandFlags flags = Comma
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, ICollection<object> args, CommandFlags flags = CommandFlags.None)
......@@ -840,8 +854,6 @@ public Task<RedisResult> ExecuteAsync(string command, ICollection<object> args,
return ExecuteAsync(msg, ResultProcessor.ScriptResult);
}
#endregion
/// <summary>
/// For testing only
/// </summary>
......
......@@ -249,7 +249,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
// PART 1: issue the pre-conditions
if (!IsAborted && conditions.Length != 0)
{
sb.AppendLine($"issuing conditions...");
sb.AppendLine("issuing conditions...");
int cmdCount = 0;
for (int i = 0; i < conditions.Length; i++)
{
......@@ -263,15 +263,15 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{
msg.SetNoRedirect(); // need to keep them in the current context only
yield return msg;
sb.AppendLine($"issuing {msg.CommandAndKey}");
sb.Append("issuing ").AppendLine(msg.CommandAndKey);
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)
{
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
multiplexer.Trace("Flushing and waiting for precondition responses");
connection.FlushAsync().Wait();
......@@ -280,14 +280,14 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
if (!AreAllConditionsSatisfied(multiplexer))
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
{ // timeout running pre-conditions
multiplexer.Trace("Timeout checking preconditions");
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);
lastBox = null;
......@@ -299,7 +299,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{
multiplexer.Trace("Begining transaction");
yield return Message.Create(-1, CommandFlags.None, RedisCommand.MULTI);
sb.AppendLine($"issued MULTI");
sb.AppendLine("issued MULTI");
}
// PART 3: issue the commands
......@@ -321,13 +321,13 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
}
}
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)
{
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");
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)
if (!op.WasQueued)
{
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;
break;
}
}
}
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
{
multiplexer.Trace("Aborting: timeout checking queued messages");
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);
lastBox = null;
......@@ -370,7 +370,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
}
if (IsAborted)
{
sb.AppendLine($"aborting {InnerOperations.Length} wrapped commands...");
sb.Append("aborting ").Append(InnerOperations.Length).AppendLine(" wrapped commands...");
connection.Trace("Aborting: canceling wrapped messages");
foreach (var op in InnerOperations)
{
......@@ -379,7 +379,7 @@ public IEnumerable<Message> GetMessages(PhysicalConnection connection)
}
}
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"
}
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