Commit 9426e1af authored by Marc Gravell's avatar Marc Gravell

add the SocketConnection ShutdownKind/SocketError to the failure outputl make...

add the SocketConnection ShutdownKind/SocketError to the failure outputl make Roslynator happy in a bunch of places
parent a52077c2
...@@ -65,7 +65,7 @@ public ServerCounters GetCounters() ...@@ -65,7 +65,7 @@ public ServerCounters GetCounters()
/// <summary> /// <summary>
/// Gets the client-name that will be used on all new connections /// Gets the client-name that will be used on all new connections
/// </summary> /// </summary>
public string ClientName => configuration.ClientName ?? GetDefaultClientName(); public string ClientName => RawConfig.ClientName ?? GetDefaultClientName();
private static string defaultClientName; private static string defaultClientName;
private static string GetDefaultClientName() private static string GetDefaultClientName()
...@@ -124,7 +124,7 @@ internal static string TryGetAzureRoleInstanceIdNoThrow() ...@@ -124,7 +124,7 @@ internal static string TryGetAzureRoleInstanceIdNoThrow()
/// <summary> /// <summary>
/// Gets the configuration of the connection /// Gets the configuration of the connection
/// </summary> /// </summary>
public string Configuration => configuration.ToString(); public string Configuration => RawConfig.ToString();
internal void OnConnectionFailed(EndPoint endpoint, ConnectionType connectionType, ConnectionFailureType failureType, Exception exception, bool reconfigure) internal void OnConnectionFailed(EndPoint endpoint, ConnectionType connectionType, ConnectionFailureType failureType, Exception exception, bool reconfigure)
{ {
...@@ -317,7 +317,7 @@ public void ExportConfiguration(Stream destination, ExportOptions options = Expo ...@@ -317,7 +317,7 @@ public void ExportConfiguration(Stream destination, ExportOptions options = Expo
internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options, TextWriter log) internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options, TextWriter log)
{ {
CommandMap.AssertAvailable(RedisCommand.SLAVEOF); CommandMap.AssertAvailable(RedisCommand.SLAVEOF);
if (!configuration.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(IncludeDetailInExceptions, RedisCommand.SLAVEOF, null, server); if (!RawConfig.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(IncludeDetailInExceptions, RedisCommand.SLAVEOF, null, server);
if (server == null) throw new ArgumentNullException(nameof(server)); if (server == null) throw new ArgumentNullException(nameof(server));
var srv = new RedisServer(this, server, null); var srv = new RedisServer(this, server, null);
...@@ -346,10 +346,10 @@ internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options ...@@ -346,10 +346,10 @@ internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options
RedisKey tieBreakerKey = default(RedisKey); RedisKey tieBreakerKey = default(RedisKey);
// try and write this everywhere; don't worry if some folks reject our advances // try and write this everywhere; don't worry if some folks reject our advances
if ((options & ReplicationChangeOptions.SetTiebreaker) != 0 && !string.IsNullOrWhiteSpace(configuration.TieBreaker) if ((options & ReplicationChangeOptions.SetTiebreaker) != 0 && !string.IsNullOrWhiteSpace(RawConfig.TieBreaker)
&& CommandMap.IsAvailable(RedisCommand.SET)) && CommandMap.IsAvailable(RedisCommand.SET))
{ {
tieBreakerKey = configuration.TieBreaker; tieBreakerKey = RawConfig.TieBreaker;
foreach (var node in nodes) foreach (var node in nodes)
{ {
...@@ -461,7 +461,7 @@ internal void LogLocked(TextWriter log, string line, params object[] args) ...@@ -461,7 +461,7 @@ internal void LogLocked(TextWriter log, string line, params object[] args)
internal void CheckMessage(Message message) internal void CheckMessage(Message message)
{ {
if (!configuration.AllowAdmin && message.IsAdmin) if (!RawConfig.AllowAdmin && message.IsAdmin)
throw ExceptionFactory.AdminModeNotEnabled(IncludeDetailInExceptions, message.Command, message, null); throw ExceptionFactory.AdminModeNotEnabled(IncludeDetailInExceptions, message.Command, message, null);
if (message.Command != RedisCommand.UNKNOWN) CommandMap.AssertAvailable(message.Command); if (message.Command != RedisCommand.UNKNOWN) CommandMap.AssertAvailable(message.Command);
...@@ -527,13 +527,11 @@ private static void WriteNormalizingLineEndings(string source, StreamWriter writ ...@@ -527,13 +527,11 @@ private static void WriteNormalizingLineEndings(string source, StreamWriter writ
/// <param name="configuredOnly">Whether to get only the endpoints specified explicitly in the config.</param> /// <param name="configuredOnly">Whether to get only the endpoints specified explicitly in the config.</param>
public EndPoint[] GetEndPoints(bool configuredOnly = false) public EndPoint[] GetEndPoints(bool configuredOnly = false)
{ {
if (configuredOnly) return configuration.EndPoints.ToArray(); if (configuredOnly) return RawConfig.EndPoints.ToArray();
return _serverSnapshot.GetEndPoints(); return _serverSnapshot.GetEndPoints();
} }
private readonly ConfigurationOptions configuration;
internal bool TryResend(int hashSlot, Message message, EndPoint endpoint, bool isMoved) internal bool TryResend(int hashSlot, Message message, EndPoint endpoint, bool isMoved)
{ {
return ServerSelectionStrategy.TryResend(hashSlot, message, endpoint, isMoved); return ServerSelectionStrategy.TryResend(hashSlot, message, endpoint, isMoved);
...@@ -966,7 +964,7 @@ private ConnectionMultiplexer(ConfigurationOptions configuration) ...@@ -966,7 +964,7 @@ private ConnectionMultiplexer(ConfigurationOptions configuration)
IncludeDetailInExceptions = true; IncludeDetailInExceptions = true;
IncludePerformanceCountersInExceptions = false; IncludePerformanceCountersInExceptions = false;
this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); RawConfig = configuration ?? throw new ArgumentNullException(nameof(configuration));
var map = CommandMap = configuration.CommandMap; var map = CommandMap = configuration.CommandMap;
if (!string.IsNullOrWhiteSpace(configuration.Password)) map.AssertAvailable(RedisCommand.AUTH); if (!string.IsNullOrWhiteSpace(configuration.Password)) map.AssertAvailable(RedisCommand.AUTH);
...@@ -1096,7 +1094,7 @@ public ISubscriber GetSubscriber(object asyncState = null) ...@@ -1096,7 +1094,7 @@ public ISubscriber GetSubscriber(object asyncState = null)
public IDatabase GetDatabase(int db = -1, object asyncState = null) public IDatabase GetDatabase(int db = -1, object asyncState = null)
{ {
if (db == -1) if (db == -1)
db = configuration.DefaultDatabase ?? 0; db = RawConfig.DefaultDatabase ?? 0;
if (db < 0) throw new ArgumentOutOfRangeException(nameof(db)); if (db < 0) throw new ArgumentOutOfRangeException(nameof(db));
if (db != 0 && RawConfig.Proxy == Proxy.Twemproxy) throw new NotSupportedException("Twemproxy only supports database 0"); if (db != 0 && RawConfig.Proxy == Proxy.Twemproxy) throw new NotSupportedException("Twemproxy only supports database 0");
...@@ -1245,7 +1243,7 @@ public bool Configure(TextWriter log = null) ...@@ -1245,7 +1243,7 @@ public bool Configure(TextWriter log = null)
if (!task.Wait(SyncConnectTimeout(false))) if (!task.Wait(SyncConnectTimeout(false)))
{ {
task.ObserveErrors(); task.ObserveErrors();
if (configuration.AbortOnConnectFail) if (RawConfig.AbortOnConnectFail)
{ {
throw new TimeoutException(); throw new TimeoutException();
} }
...@@ -1263,7 +1261,7 @@ internal int SyncConnectTimeout(bool forConnect) ...@@ -1263,7 +1261,7 @@ internal int SyncConnectTimeout(bool forConnect)
int retryCount = forConnect ? RawConfig.ConnectRetry : 1; int retryCount = forConnect ? RawConfig.ConnectRetry : 1;
if (retryCount <= 0) retryCount = 1; if (retryCount <= 0) retryCount = 1;
int timeout = configuration.ConnectTimeout; int timeout = RawConfig.ConnectTimeout;
if (timeout >= int.MaxValue / retryCount) return int.MaxValue; if (timeout >= int.MaxValue / retryCount) return int.MaxValue;
timeout *= retryCount; timeout *= retryCount;
...@@ -1337,28 +1335,28 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text ...@@ -1337,28 +1335,28 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
Trace("Starting reconfiguration..."); Trace("Starting reconfiguration...");
Trace(blame != null, "Blaming: " + Format.ToString(blame)); Trace(blame != null, "Blaming: " + Format.ToString(blame));
LogLocked(log, configuration.ToString(includePassword: false)); LogLocked(log, RawConfig.ToString(includePassword: false));
LogLocked(log, ""); LogLocked(log, "");
if (first) if (first)
{ {
if (configuration.ResolveDns && configuration.HasDnsEndPoints()) if (RawConfig.ResolveDns && RawConfig.HasDnsEndPoints())
{ {
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
var dns = configuration.ResolveEndPointsAsync(this, log).ObserveErrors(); var dns = RawConfig.ResolveEndPointsAsync(this, log).ObserveErrors();
if ((await Task.WhenAny(dns, Task.Delay(TimeoutMilliseconds, cts.Token)).ForAwait()) != dns) if ((await Task.WhenAny(dns, Task.Delay(TimeoutMilliseconds, cts.Token)).ForAwait()) != dns)
{ {
throw new TimeoutException("Timeout resolving endpoints"); throw new TimeoutException("Timeout resolving endpoints");
} }
cts.Cancel(); cts.Cancel();
} }
foreach (var endpoint in configuration.EndPoints) foreach (var endpoint in RawConfig.EndPoints)
{ {
GetServerEndPoint(endpoint, log, false); GetServerEndPoint(endpoint, log, false);
} }
ActivateAllServers(log); ActivateAllServers(log);
} }
int attemptsLeft = first ? configuration.ConnectRetry : 1; int attemptsLeft = first ? RawConfig.ConnectRetry : 1;
bool healthy = false; bool healthy = false;
do do
...@@ -1368,7 +1366,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text ...@@ -1368,7 +1366,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
attemptsLeft--; attemptsLeft--;
} }
int standaloneCount = 0, clusterCount = 0, sentinelCount = 0; int standaloneCount = 0, clusterCount = 0, sentinelCount = 0;
var endpoints = configuration.EndPoints; var endpoints = RawConfig.EndPoints;
LogLocked(log, "{0} unique nodes specified", endpoints.Count); LogLocked(log, "{0} unique nodes specified", endpoints.Count);
if (endpoints.Count == 0) if (endpoints.Count == 0)
...@@ -1379,7 +1377,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text ...@@ -1379,7 +1377,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
const CommandFlags flags = CommandFlags.NoRedirect | CommandFlags.HighPriority; const CommandFlags flags = CommandFlags.NoRedirect | CommandFlags.HighPriority;
#pragma warning restore CS0618 #pragma warning restore CS0618
List<ServerEndPoint> masters = new List<ServerEndPoint>(endpoints.Count); List<ServerEndPoint> masters = new List<ServerEndPoint>(endpoints.Count);
bool useTieBreakers = !string.IsNullOrWhiteSpace(configuration.TieBreaker); bool useTieBreakers = !string.IsNullOrWhiteSpace(RawConfig.TieBreaker);
ServerEndPoint[] servers = null; ServerEndPoint[] servers = null;
Task<string>[] tieBreakers = null; Task<string>[] tieBreakers = null;
...@@ -1401,7 +1399,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text ...@@ -1401,7 +1399,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
tieBreakers = useTieBreakers ? new Task<string>[endpoints.Count] : null; tieBreakers = useTieBreakers ? new Task<string>[endpoints.Count] : null;
servers = new ServerEndPoint[available.Length]; servers = new ServerEndPoint[available.Length];
RedisKey tieBreakerKey = useTieBreakers ? (RedisKey)configuration.TieBreaker : default(RedisKey); RedisKey tieBreakerKey = useTieBreakers ? (RedisKey)RawConfig.TieBreaker : default(RedisKey);
for (int i = 0; i < available.Length; i++) for (int i = 0; i < available.Length; i++)
{ {
...@@ -1419,7 +1417,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text ...@@ -1419,7 +1417,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
available[i] = server.SendTracer(log); available[i] = server.SendTracer(log);
if (useTieBreakers) if (useTieBreakers)
{ {
LogLocked(log, "Requesting tie-break from {0} > {1}...", Format.ToString(server.EndPoint), configuration.TieBreaker); LogLocked(log, "Requesting tie-break from {0} > {1}...", Format.ToString(server.EndPoint), RawConfig.TieBreaker);
Message msg = Message.Create(0, flags, RedisCommand.GET, tieBreakerKey); Message msg = Message.Create(0, flags, RedisCommand.GET, tieBreakerKey);
msg.SetInternalCall(); msg.SetInternalCall();
msg = LoggingMessage.Create(log, msg); msg = LoggingMessage.Create(log, msg);
...@@ -1428,7 +1426,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text ...@@ -1428,7 +1426,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
} }
watch = watch ?? Stopwatch.StartNew(); watch = watch ?? Stopwatch.StartNew();
var remaining = configuration.ConnectTimeout - checked((int)watch.ElapsedMilliseconds); var remaining = RawConfig.ConnectTimeout - checked((int)watch.ElapsedMilliseconds);
LogLocked(log, "Allowing endpoints {0} to respond...", TimeSpan.FromMilliseconds(remaining)); LogLocked(log, "Allowing endpoints {0} to respond...", TimeSpan.FromMilliseconds(remaining));
Trace("Allowing endpoints " + TimeSpan.FromMilliseconds(remaining) + " to respond..."); Trace("Allowing endpoints " + TimeSpan.FromMilliseconds(remaining) + " to respond...");
await WaitAllIgnoreErrorsAsync(available, remaining, log).ForAwait(); await WaitAllIgnoreErrorsAsync(available, remaining, log).ForAwait();
...@@ -1598,7 +1596,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text ...@@ -1598,7 +1596,7 @@ internal async Task<bool> ReconfigureAsync(bool first, bool reconfigureAll, Text
//WTF("?: " + attempts); //WTF("?: " + attempts);
} while (first && !healthy && attemptsLeft > 0); } while (first && !healthy && attemptsLeft > 0);
if (first && configuration.AbortOnConnectFail && !healthy) if (first && RawConfig.AbortOnConnectFail && !healthy)
{ {
return false; return false;
} }
...@@ -1941,7 +1939,7 @@ public bool IsConnecting ...@@ -1941,7 +1939,7 @@ public bool IsConnecting
} }
} }
internal ConfigurationOptions RawConfig => configuration; internal ConfigurationOptions RawConfig { get; }
internal ServerSelectionStrategy ServerSelectionStrategy { get; } internal ServerSelectionStrategy ServerSelectionStrategy { get; }
...@@ -2015,7 +2013,7 @@ public async Task CloseAsync(bool allowCommandsToComplete = true) ...@@ -2015,7 +2013,7 @@ public async Task CloseAsync(bool allowCommandsToComplete = true)
if (allowCommandsToComplete) if (allowCommandsToComplete)
{ {
var quits = QuitAllServers(); var quits = QuitAllServers();
await WaitAllIgnoreErrorsAsync(quits, configuration.AsyncTimeout, null).ForAwait(); await WaitAllIgnoreErrorsAsync(quits, RawConfig.AsyncTimeout, null).ForAwait();
} }
DisposeAndClearServers(); DisposeAndClearServers();
......
...@@ -125,7 +125,7 @@ internal static Exception NoConnectionAvailable(bool includeDetail, bool include ...@@ -125,7 +125,7 @@ internal static Exception NoConnectionAvailable(bool includeDetail, bool include
internal static Exception PopulateInnerExceptions(ReadOnlySpan<ServerEndPoint> serverSnapshot) internal static Exception PopulateInnerExceptions(ReadOnlySpan<ServerEndPoint> serverSnapshot)
{ {
var innerExceptions = new List<Exception>(); var innerExceptions = new List<Exception>();
if (serverSnapshot.Length > 0 && serverSnapshot[0].Multiplexer.LastException != null) if (serverSnapshot.Length > 0 && serverSnapshot[0].Multiplexer.LastException != null)
{ {
innerExceptions.Add(serverSnapshot[0].Multiplexer.LastException); innerExceptions.Add(serverSnapshot[0].Multiplexer.LastException);
...@@ -195,10 +195,6 @@ private static string GetLabel(bool includeDetail, RedisCommand command, Message ...@@ -195,10 +195,6 @@ private static string GetLabel(bool includeDetail, RedisCommand command, Message
return message == null ? command.ToString() : (includeDetail ? message.CommandAndKey : message.Command.ToString()); return message == null ? command.ToString() : (includeDetail ? message.CommandAndKey : message.Command.ToString());
} }
private static string GetLabel(bool includeDetail, string command, Message message)
{
return message == null ? command : (includeDetail ? message.CommandAndKey : message.Command.ToString());
}
internal static Exception UnableToConnect(ConnectionMultiplexer muxer, string failureMessage=null) internal static Exception UnableToConnect(ConnectionMultiplexer muxer, string failureMessage=null)
{ {
var sb = new StringBuilder("It was not possible to connect to the redis server(s)."); var sb = new StringBuilder("It was not possible to connect to the redis server(s).");
......
...@@ -275,7 +275,8 @@ public Task FlushAsync() ...@@ -275,7 +275,8 @@ public Task FlushAsync()
return Task.CompletedTask; return Task.CompletedTask;
} }
public void RecordConnectionFailed(ConnectionFailureType failureType, Exception innerException = null, [CallerMemberName] string origin = null, bool isInitialConnect = false) public void RecordConnectionFailed(ConnectionFailureType failureType, Exception innerException = null, [CallerMemberName] string origin = null,
bool isInitialConnect = false, IDuplexPipe connectingPipe = null)
{ {
Exception outerException = innerException; Exception outerException = innerException;
IdentifyFailureType(innerException, ref failureType); IdentifyFailureType(innerException, ref failureType);
...@@ -307,6 +308,16 @@ public void RecordConnectionFailed(ConnectionFailureType failureType, Exception ...@@ -307,6 +308,16 @@ public void RecordConnectionFailed(ConnectionFailureType failureType, Exception
var exMessage = new StringBuilder(failureType.ToString()); var exMessage = new StringBuilder(failureType.ToString());
if ((connectingPipe ?? _ioPipe) is SocketConnection sc)
{
exMessage.Append(" (").Append(sc.ShutdownKind);
if (sc.SocketError != SocketError.Success)
{
exMessage.Append("/").Append(sc.SocketError);
}
exMessage.Append(")");
}
var data = new List<Tuple<string, string>>(); var data = new List<Tuple<string, string>>();
if (IncludeDetailInExceptions) if (IncludeDetailInExceptions)
{ {
...@@ -1082,6 +1093,7 @@ internal async ValueTask<bool> ConnectedAsync(Socket socket, TextWriter log, Soc ...@@ -1082,6 +1093,7 @@ internal async ValueTask<bool> ConnectedAsync(Socket socket, TextWriter log, Soc
var bridge = BridgeCouldBeNull; var bridge = BridgeCouldBeNull;
if (bridge == null) return false; if (bridge == null) return false;
IDuplexPipe pipe = null;
try try
{ {
// disallow connection in some cases // disallow connection in some cases
...@@ -1093,7 +1105,6 @@ internal async ValueTask<bool> ConnectedAsync(Socket socket, TextWriter log, Soc ...@@ -1093,7 +1105,6 @@ internal async ValueTask<bool> ConnectedAsync(Socket socket, TextWriter log, Soc
var config = bridge.Multiplexer.RawConfig; var config = bridge.Multiplexer.RawConfig;
IDuplexPipe pipe;
if (config.Ssl) if (config.Ssl)
{ {
bridge.Multiplexer.LogLocked(log, "Configuring SSL"); bridge.Multiplexer.LogLocked(log, "Configuring SSL");
...@@ -1141,7 +1152,7 @@ internal async ValueTask<bool> ConnectedAsync(Socket socket, TextWriter log, Soc ...@@ -1141,7 +1152,7 @@ internal async ValueTask<bool> ConnectedAsync(Socket socket, TextWriter log, Soc
} }
catch (Exception ex) catch (Exception ex)
{ {
RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex, isInitialConnect: true); // includes a bridge.OnDisconnected RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex, isInitialConnect: true, connectingPipe: pipe); // includes a bridge.OnDisconnected
bridge.Multiplexer.Trace("Could not connect: " + ex.Message, physicalName); bridge.Multiplexer.Trace("Could not connect: " + ex.Message, physicalName);
return false; return false;
} }
......
...@@ -1737,7 +1737,7 @@ protected NameValueEntry[] ParseStreamEntryValues(RawResult result) ...@@ -1737,7 +1737,7 @@ protected NameValueEntry[] ParseStreamEntryValues(RawResult result)
} }
var arr = result.GetItems(); var arr = result.GetItems();
// Calculate how many name/value pairs are in the stream entry. // Calculate how many name/value pairs are in the stream entry.
int count = arr.Length / 2; int count = arr.Length / 2;
......
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