Commit 53906c6d authored by Marc Gravell's avatar Marc Gravell

Add IncludePerformanceCountersInExceptions (defaults to false) to fix #587...

Add IncludePerformanceCountersInExceptions (defaults to false) to fix #587 (also fix broken nunit reference in one of the tests)
parent 2b9a2a5f
...@@ -9,7 +9,7 @@ namespace Tests.Issues ...@@ -9,7 +9,7 @@ namespace Tests.Issues
[TestFixture] [TestFixture]
public class Massive_Delete public class Massive_Delete
{ {
[TestFixtureSetUp] [OneTimeSetUpAttribute]
public void Init() public void Init()
{ {
using (var muxer = Config.GetUnsecuredConnection(allowAdmin: true)) using (var muxer = Config.GetUnsecuredConnection(allowAdmin: true))
......
...@@ -44,10 +44,6 @@ ...@@ -44,10 +44,6 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="nunit.framework, Version=3.0.5797.27534, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.0.0\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
......
...@@ -40,8 +40,8 @@ select new ...@@ -40,8 +40,8 @@ select new
Type = type, Type = type,
Methods = methods, Methods = methods,
ActiveMethods = methods.Where(x => Attribute.IsDefined(x, typeof(ActiveTestAttribute))).ToArray(), ActiveMethods = methods.Where(x => Attribute.IsDefined(x, typeof(ActiveTestAttribute))).ToArray(),
Setup = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(TestFixtureSetUpAttribute))), Setup = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(OneTimeSetUpAttribute))),
TearDown = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(TestFixtureTearDownAttribute))) TearDown = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(OneTimeTearDownAttribute)))
}; };
int pass = 0, fail = 0; int pass = 0, fail = 0;
......
...@@ -13,7 +13,7 @@ public void NullLastException() ...@@ -13,7 +13,7 @@ public void NullLastException()
{ {
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
Assert.Null(muxer.GetServerSnapshot()[0].LastException); Assert.Null(muxer.GetServerSnapshot()[0].LastException);
var ex = ExceptionFactory.NoConnectionAvailable(true, new RedisCommand(), null, null, muxer.GetServerSnapshot()); var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null, null, muxer.GetServerSnapshot());
Assert.Null(ex.InnerException); Assert.Null(ex.InnerException);
} }
...@@ -22,7 +22,7 @@ public void NullLastException() ...@@ -22,7 +22,7 @@ public void NullLastException()
[Test] [Test]
public void NullSnapshot() public void NullSnapshot()
{ {
var ex = ExceptionFactory.NoConnectionAvailable(true, new RedisCommand(), null, null, null); var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null, null, null);
Assert.Null(ex.InnerException); Assert.Null(ex.InnerException);
} }
#if DEBUG // needs debug connection features #if DEBUG // needs debug connection features
...@@ -42,7 +42,7 @@ public void MultipleEndpointsThrowAggregateException() ...@@ -42,7 +42,7 @@ public void MultipleEndpointsThrowAggregateException()
muxer.GetServer(endpoint).SimulateConnectionFailure(); muxer.GetServer(endpoint).SimulateConnectionFailure();
} }
var ex = ExceptionFactory.NoConnectionAvailable(true, new RedisCommand(), null, null, muxer.GetServerSnapshot()); var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null, null, muxer.GetServerSnapshot());
Assert.IsInstanceOf<RedisConnectionException>(ex); Assert.IsInstanceOf<RedisConnectionException>(ex);
Assert.IsInstanceOf<AggregateException>(ex.InnerException); Assert.IsInstanceOf<AggregateException>(ex.InnerException);
var aggException = (AggregateException)ex.InnerException; var aggException = (AggregateException)ex.InnerException;
...@@ -70,7 +70,7 @@ public void NullInnerExceptionForMultipleEndpointsWithNoLastException() ...@@ -70,7 +70,7 @@ public void NullInnerExceptionForMultipleEndpointsWithNoLastException()
var conn = muxer.GetDatabase(); var conn = muxer.GetDatabase();
muxer.AllowConnect = false; muxer.AllowConnect = false;
SocketManager.ConnectCompletionType = CompletionType.Async; SocketManager.ConnectCompletionType = CompletionType.Async;
var ex = ExceptionFactory.NoConnectionAvailable(true, new RedisCommand(), null, null, muxer.GetServerSnapshot()); var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null, null, muxer.GetServerSnapshot());
Assert.IsInstanceOf<RedisConnectionException>(ex); Assert.IsInstanceOf<RedisConnectionException>(ex);
Assert.Null(ex.InnerException); Assert.Null(ex.InnerException);
} }
...@@ -95,7 +95,7 @@ public void ServerTakesPrecendenceOverSnapshot() ...@@ -95,7 +95,7 @@ public void ServerTakesPrecendenceOverSnapshot()
muxer.GetServer(muxer.GetEndPoints()[0]).SimulateConnectionFailure(); muxer.GetServer(muxer.GetEndPoints()[0]).SimulateConnectionFailure();
var ex = ExceptionFactory.NoConnectionAvailable(true, new RedisCommand(), null,muxer.GetServerSnapshot()[0], muxer.GetServerSnapshot()); var ex = ExceptionFactory.NoConnectionAvailable(true, true, new RedisCommand(), null,muxer.GetServerSnapshot()[0], muxer.GetServerSnapshot());
Assert.IsInstanceOf<RedisConnectionException>(ex); Assert.IsInstanceOf<RedisConnectionException>(ex);
Assert.IsInstanceOf<Exception>(ex.InnerException); Assert.IsInstanceOf<Exception>(ex.InnerException);
Assert.That(muxer.GetServerSnapshot()[0].LastException, Is.EqualTo(ex.InnerException)); Assert.That(muxer.GetServerSnapshot()[0].LastException, Is.EqualTo(ex.InnerException));
......
...@@ -351,7 +351,7 @@ internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options ...@@ -351,7 +351,7 @@ internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options
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);
if (!srv.IsConnected) throw ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, RedisCommand.SLAVEOF, null, server, GetServerSnapshot()); if (!srv.IsConnected) throw ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, IncludePerformanceCountersInExceptions, RedisCommand.SLAVEOF, null, server, GetServerSnapshot());
if (log == null) log = TextWriter.Null; if (log == null) log = TextWriter.Null;
CommandMap.AssertAvailable(RedisCommand.SLAVEOF); CommandMap.AssertAvailable(RedisCommand.SLAVEOF);
...@@ -935,6 +935,7 @@ private ConnectionMultiplexer(ConfigurationOptions configuration) ...@@ -935,6 +935,7 @@ private ConnectionMultiplexer(ConfigurationOptions configuration)
{ {
if (configuration == null) throw new ArgumentNullException(nameof(configuration)); if (configuration == null) throw new ArgumentNullException(nameof(configuration));
IncludeDetailInExceptions = true; IncludeDetailInExceptions = true;
IncludePerformanceCountersInExceptions = false;
this.configuration = configuration; this.configuration = configuration;
...@@ -1964,7 +1965,7 @@ internal Task<T> ExecuteAsyncImpl<T>(Message message, ResultProcessor<T> process ...@@ -1964,7 +1965,7 @@ internal Task<T> ExecuteAsyncImpl<T>(Message message, ResultProcessor<T> process
var source = ResultBox<T>.Get(tcs); var source = ResultBox<T>.Get(tcs);
if (!TryPushMessageToBridge(message, processor, source, ref server)) if (!TryPushMessageToBridge(message, processor, source, ref server))
{ {
ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, message.Command, message, server, GetServerSnapshot())); ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, IncludePerformanceCountersInExceptions, message.Command, message, server, GetServerSnapshot()));
} }
return tcs.Task; return tcs.Task;
} }
...@@ -2005,7 +2006,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser ...@@ -2005,7 +2006,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
{ {
if (!TryPushMessageToBridge(message, processor, source, ref server)) if (!TryPushMessageToBridge(message, processor, source, ref server))
{ {
throw ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, message.Command, message, server, GetServerSnapshot()); throw ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, IncludePerformanceCountersInExceptions, message.Command, message, server, GetServerSnapshot());
} }
if (Monitor.Wait(source, timeoutMilliseconds)) if (Monitor.Wait(source, timeoutMilliseconds))
...@@ -2068,7 +2069,10 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser ...@@ -2068,7 +2069,10 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
add("ThreadPool-Workers", "WORKER", worker); add("ThreadPool-Workers", "WORKER", worker);
data.Add(Tuple.Create("Busy-Workers", busyWorkerCount.ToString())); data.Add(Tuple.Create("Busy-Workers", busyWorkerCount.ToString()));
add("Local-CPU", "Local-CPU", GetSystemCpuPercent()); if (IncludePerformanceCountersInExceptions)
{
add("Local-CPU", "Local-CPU", GetSystemCpuPercent());
}
#endif #endif
sb.Append(" (Please take a look at this article for some common client-side issues that can cause timeouts: "); sb.Append(" (Please take a look at this article for some common client-side issues that can cause timeouts: ");
sb.Append(timeoutHelpLink); sb.Append(timeoutHelpLink);
...@@ -2106,11 +2110,11 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser ...@@ -2106,11 +2110,11 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
} }
#if !CORE_CLR #if !CORE_CLR
internal static string GetThreadPoolAndCPUSummary() internal static string GetThreadPoolAndCPUSummary(bool includePerformanceCounters)
{ {
string iocp, worker; string iocp, worker;
GetThreadPoolStats(out iocp, out worker); GetThreadPoolStats(out iocp, out worker);
var cpu = GetSystemCpuPercent(); var cpu = includePerformanceCounters ? GetSystemCpuPercent() : "n/a";
return $"IOCP: {iocp}, WORKER: {worker}, Local-CPU: {cpu}"; return $"IOCP: {iocp}, WORKER: {worker}, Local-CPU: {cpu}";
} }
...@@ -2150,7 +2154,12 @@ private static int GetThreadPoolStats(out string iocp, out string worker) ...@@ -2150,7 +2154,12 @@ private static int GetThreadPoolStats(out string iocp, out string worker)
/// <summary> /// <summary>
/// Should exceptions include identifiable details? (key names, additional .Data annotations) /// Should exceptions include identifiable details? (key names, additional .Data annotations)
/// </summary> /// </summary>
public bool IncludeDetailInExceptions { get; set; } public bool IncludeDetailInExceptions { get; set; }
/// <summary>
/// Should exceptions include performance counter details? (CPU usage, etc - note that this can be problematic on some platforms)
/// </summary>
public bool IncludePerformanceCountersInExceptions { get; set; }
int haveStormLog = 0, stormLogThreshold = 15; int haveStormLog = 0, stormLogThreshold = 15;
string stormLogSnapshot; string stormLogSnapshot;
......
...@@ -92,7 +92,7 @@ internal static string GetInnerMostExceptionMessage(Exception e) ...@@ -92,7 +92,7 @@ internal static string GetInnerMostExceptionMessage(Exception e)
} }
} }
internal static Exception NoConnectionAvailable(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server, ServerEndPoint[] serverSnapshot) internal static Exception NoConnectionAvailable(bool includeDetail, bool includePerformanceCounters, RedisCommand command, Message message, ServerEndPoint server, ServerEndPoint[] serverSnapshot)
{ {
string commandLabel = GetLabel(includeDetail, command, message); string commandLabel = GetLabel(includeDetail, command, message);
...@@ -115,7 +115,7 @@ internal static Exception NoConnectionAvailable(bool includeDetail, RedisCommand ...@@ -115,7 +115,7 @@ internal static Exception NoConnectionAvailable(bool includeDetail, RedisCommand
#if !CORE_CLR #if !CORE_CLR
if (includeDetail) if (includeDetail)
{ {
exceptionmessage.Append("; ").Append(ConnectionMultiplexer.GetThreadPoolAndCPUSummary()); exceptionmessage.Append("; ").Append(ConnectionMultiplexer.GetThreadPoolAndCPUSummary(includePerformanceCounters));
} }
#endif #endif
......
...@@ -266,7 +266,7 @@ internal void KeepAlive() ...@@ -266,7 +266,7 @@ internal void KeepAlive()
Multiplexer.Trace("Enqueue: " + msg); Multiplexer.Trace("Enqueue: " + msg);
if (!TryEnqueue(msg, ServerEndPoint.IsSlave)) if (!TryEnqueue(msg, ServerEndPoint.IsSlave))
{ {
OnInternalError(ExceptionFactory.NoConnectionAvailable(Multiplexer.IncludeDetailInExceptions, msg.Command, msg, ServerEndPoint, Multiplexer.GetServerSnapshot())); OnInternalError(ExceptionFactory.NoConnectionAvailable(Multiplexer.IncludeDetailInExceptions, Multiplexer.IncludePerformanceCountersInExceptions, msg.Command, msg, ServerEndPoint, Multiplexer.GetServerSnapshot()));
} }
} }
} }
......
...@@ -30,13 +30,13 @@ public void Execute() ...@@ -30,13 +30,13 @@ public void Execute()
if (server == null) if (server == null)
{ {
FailNoServer(snapshot); FailNoServer(snapshot);
throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server,multiplexer.GetServerSnapshot()); throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server,multiplexer.GetServerSnapshot());
} }
var bridge = server.GetBridge(message.Command); var bridge = server.GetBridge(message.Command);
if (bridge == null) if (bridge == null)
{ {
FailNoServer(snapshot); FailNoServer(snapshot);
throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot()); throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot());
} }
// identity a list // identity a list
......
...@@ -553,7 +553,7 @@ internal override Task<T> ExecuteAsync<T>(Message message, ResultProcessor<T> pr ...@@ -553,7 +553,7 @@ internal override Task<T> ExecuteAsync<T>(Message message, ResultProcessor<T> pr
// no need to deny exec-sync here; will be complete before they see if // no need to deny exec-sync here; will be complete before they see if
var tcs = TaskSource.Create<T>(asyncState); var tcs = TaskSource.Create<T>(asyncState);
ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot())); ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot()));
return tcs.Task; return tcs.Task;
} }
return base.ExecuteAsync<T>(message, processor, server); return base.ExecuteAsync<T>(message, processor, server);
...@@ -566,7 +566,7 @@ internal override T ExecuteSync<T>(Message message, ResultProcessor<T> processor ...@@ -566,7 +566,7 @@ internal override T ExecuteSync<T>(Message message, ResultProcessor<T> processor
if (!server.IsConnected) if (!server.IsConnected)
{ {
if (message == null || message.IsFireAndForget) return default(T); if (message == null || message.IsFireAndForget) return default(T);
throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot()); throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot());
} }
return base.ExecuteSync<T>(message, processor, server); return base.ExecuteSync<T>(message, processor, server);
} }
......
...@@ -177,7 +177,7 @@ public virtual bool SetResult(PhysicalConnection connection, Message message, Ra ...@@ -177,7 +177,7 @@ public virtual bool SetResult(PhysicalConnection connection, Message message, Ra
{ {
err = string.Format("Endpoint {0} serving hashslot {1} is not reachable at this point of time. Please check connectTimeout value. If it is low, try increasing it to give the ConnectionMultiplexer a chance to recover from the network disconnect. ", endpoint, hashSlot); err = string.Format("Endpoint {0} serving hashslot {1} is not reachable at this point of time. Please check connectTimeout value. If it is low, try increasing it to give the ConnectionMultiplexer a chance to recover from the network disconnect. ", endpoint, hashSlot);
#if !CORE_CLR #if !CORE_CLR
err += ConnectionMultiplexer.GetThreadPoolAndCPUSummary(); err += ConnectionMultiplexer.GetThreadPoolAndCPUSummary(bridge.Multiplexer.IncludePerformanceCountersInExceptions);
#endif #endif
} }
} }
......
...@@ -564,7 +564,7 @@ internal Task<T> QueueDirectAsync<T>(Message message, ResultProcessor<T> process ...@@ -564,7 +564,7 @@ internal Task<T> QueueDirectAsync<T>(Message message, ResultProcessor<T> process
if (bridge == null) bridge = GetBridge(message.Command); if (bridge == null) bridge = GetBridge(message.Command);
if (!bridge.TryEnqueue(message, isSlave)) if (!bridge.TryEnqueue(message, isSlave))
{ {
ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, this, multiplexer.GetServerSnapshot())); ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, this, multiplexer.GetServerSnapshot()));
} }
return tcs.Task; return tcs.Task;
} }
......
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