Commit 5e6f36d2 authored by Marc Gravell's avatar Marc Gravell

better logging of any connect failures that happen during the initial connect/handshake

parent 476f8e2f
...@@ -769,12 +769,17 @@ internal ServerEndPoint AnyConnected(ServerType serverType, uint startOffset, Re ...@@ -769,12 +769,17 @@ internal ServerEndPoint AnyConnected(ServerType serverType, uint startOffset, Re
/// </summary> /// </summary>
/// <param name="configuration">The string configuration to use for this multiplexer.</param> /// <param name="configuration">The string configuration to use for this multiplexer.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param> /// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static async Task<ConnectionMultiplexer> ConnectAsync(string configuration, TextWriter log = null) public static Task<ConnectionMultiplexer> ConnectAsync(string configuration, TextWriter log = null)
=> ConnectImplAsync(configuration, log);
private static async Task<ConnectionMultiplexer> ConnectImplAsync(object configuration, TextWriter log = null)
{ {
IDisposable killMe = null; IDisposable killMe = null;
EventHandler<ConnectionFailedEventArgs> connectHandler = null;
ConnectionMultiplexer muxer = null;
try try
{ {
var muxer = CreateMultiplexer(configuration); muxer = CreateMultiplexer(configuration, log, out connectHandler);
killMe = muxer; killMe = muxer;
bool configured = await muxer.ReconfigureAsync(true, false, log, null, "connect").ObserveErrors().ForAwait(); bool configured = await muxer.ReconfigureAsync(true, false, log, null, "connect").ObserveErrors().ForAwait();
if (!configured) if (!configured)
...@@ -786,6 +791,7 @@ public static async Task<ConnectionMultiplexer> ConnectAsync(string configuratio ...@@ -786,6 +791,7 @@ public static async Task<ConnectionMultiplexer> ConnectAsync(string configuratio
} }
finally finally
{ {
if (connectHandler != null) muxer.ConnectionFailed -= connectHandler;
if (killMe != null) try { killMe.Dispose(); } catch { } if (killMe != null) try { killMe.Dispose(); } catch { }
} }
} }
...@@ -795,28 +801,10 @@ public static async Task<ConnectionMultiplexer> ConnectAsync(string configuratio ...@@ -795,28 +801,10 @@ public static async Task<ConnectionMultiplexer> ConnectAsync(string configuratio
/// </summary> /// </summary>
/// <param name="configuration">The configuration options to use for this multiplexer.</param> /// <param name="configuration">The configuration options to use for this multiplexer.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param> /// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static async Task<ConnectionMultiplexer> ConnectAsync(ConfigurationOptions configuration, TextWriter log = null) public static Task<ConnectionMultiplexer> ConnectAsync(ConfigurationOptions configuration, TextWriter log = null)
{ => ConnectImplAsync(configuration, log);
IDisposable killMe = null;
try
{
var muxer = CreateMultiplexer(configuration);
killMe = muxer;
bool configured = await muxer.ReconfigureAsync(true, false, log, null, "connect").ObserveErrors().ForAwait();
if (!configured)
{
throw ExceptionFactory.UnableToConnect(muxer, muxer.failureMessage);
}
killMe = null;
return muxer;
}
finally
{
if (killMe != null) try { killMe.Dispose(); } catch { }
}
}
private static ConnectionMultiplexer CreateMultiplexer(object configuration) private static ConnectionMultiplexer CreateMultiplexer(object configuration, TextWriter log, out EventHandler<ConnectionFailedEventArgs> connectHandler)
{ {
if (configuration == null) throw new ArgumentNullException(nameof(configuration)); if (configuration == null) throw new ArgumentNullException(nameof(configuration));
ConfigurationOptions config; ConfigurationOptions config;
...@@ -830,11 +818,35 @@ private static ConnectionMultiplexer CreateMultiplexer(object configuration) ...@@ -830,11 +818,35 @@ private static ConnectionMultiplexer CreateMultiplexer(object configuration)
} }
else else
{ {
throw new ArgumentException("configuration"); throw new ArgumentException("Invalid configuration object", nameof(configuration));
} }
if (config.EndPoints.Count == 0) throw new ArgumentException("No endpoints specified", nameof(configuration)); if (config.EndPoints.Count == 0) throw new ArgumentException("No endpoints specified", nameof(configuration));
config.SetDefaultPorts(); config.SetDefaultPorts();
return new ConnectionMultiplexer(config); var muxer = new ConnectionMultiplexer(config);
connectHandler = null;
if(log != null)
{
// create a detachable event-handler to log detailed errors if something happens during connect/handshake
connectHandler = (_, a) =>
{
try
{
lock (muxer.LogSyncLock) // keep the outer and any inner errors contiguous
{
var ex = a.Exception;
log.WriteLine($"connection failed: {Format.ToString(a.EndPoint)} ({a.ConnectionType}, {a.FailureType}): {ex?.Message ?? "(unknown)"}");
while ((ex = ex.InnerException) != null)
{
log.Write("> ");
log.WriteLine(ex.Message);
}
}
}
catch { }
};
muxer.ConnectionFailed += connectHandler;
}
return muxer;
} }
/// <summary> /// <summary>
...@@ -843,9 +855,7 @@ private static ConnectionMultiplexer CreateMultiplexer(object configuration) ...@@ -843,9 +855,7 @@ private static ConnectionMultiplexer CreateMultiplexer(object configuration)
/// <param name="configuration">The string configuration to use for this multiplexer.</param> /// <param name="configuration">The string configuration to use for this multiplexer.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param> /// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static ConnectionMultiplexer Connect(string configuration, TextWriter log = null) public static ConnectionMultiplexer Connect(string configuration, TextWriter log = null)
{ => ConnectImpl(configuration, log);
return ConnectImpl(() => CreateMultiplexer(configuration), log);
}
/// <summary> /// <summary>
/// Create a new ConnectionMultiplexer instance /// Create a new ConnectionMultiplexer instance
...@@ -853,16 +863,16 @@ public static ConnectionMultiplexer Connect(string configuration, TextWriter log ...@@ -853,16 +863,16 @@ public static ConnectionMultiplexer Connect(string configuration, TextWriter log
/// <param name="configuration">The configurtion options to use for this multiplexer.</param> /// <param name="configuration">The configurtion options to use for this multiplexer.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param> /// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static ConnectionMultiplexer Connect(ConfigurationOptions configuration, TextWriter log = null) public static ConnectionMultiplexer Connect(ConfigurationOptions configuration, TextWriter log = null)
{ => ConnectImpl(configuration, log);
return ConnectImpl(() => CreateMultiplexer(configuration), log);
}
private static ConnectionMultiplexer ConnectImpl(Func<ConnectionMultiplexer> multiplexerFactory, TextWriter log) private static ConnectionMultiplexer ConnectImpl(object configuration, TextWriter log)
{ {
IDisposable killMe = null; IDisposable killMe = null;
EventHandler<ConnectionFailedEventArgs> connectHandler = null;
ConnectionMultiplexer muxer = null;
try try
{ {
var muxer = multiplexerFactory(); muxer = CreateMultiplexer(configuration, log, out connectHandler);
killMe = muxer; killMe = muxer;
// note that task has timeouts internally, so it might take *just over* the regular timeout // note that task has timeouts internally, so it might take *just over* the regular timeout
var task = muxer.ReconfigureAsync(true, false, log, null, "connect"); var task = muxer.ReconfigureAsync(true, false, log, null, "connect");
...@@ -885,6 +895,7 @@ private static ConnectionMultiplexer ConnectImpl(Func<ConnectionMultiplexer> mul ...@@ -885,6 +895,7 @@ private static ConnectionMultiplexer ConnectImpl(Func<ConnectionMultiplexer> mul
} }
finally finally
{ {
if (connectHandler != null) muxer.ConnectionFailed -= connectHandler;
if (killMe != null) try { killMe.Dispose(); } catch { } if (killMe != null) try { killMe.Dispose(); } catch { }
} }
} }
......
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