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
[TestFixture]
public class Massive_Delete
{
[TestFixtureSetUp]
[OneTimeSetUpAttribute]
public void Init()
{
using (var muxer = Config.GetUnsecuredConnection(allowAdmin: true))
......
......@@ -44,10 +44,6 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<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.Core" />
<Reference Include="System.Xml.Linq" />
......
......@@ -40,8 +40,8 @@ select new
Type = type,
Methods = methods,
ActiveMethods = methods.Where(x => Attribute.IsDefined(x, typeof(ActiveTestAttribute))).ToArray(),
Setup = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(TestFixtureSetUpAttribute))),
TearDown = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(TestFixtureTearDownAttribute)))
Setup = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(OneTimeSetUpAttribute))),
TearDown = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(OneTimeTearDownAttribute)))
};
int pass = 0, fail = 0;
......
......@@ -13,7 +13,7 @@ public void NullLastException()
{
var conn = muxer.GetDatabase();
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);
}
......@@ -22,7 +22,7 @@ public void NullLastException()
[Test]
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);
}
#if DEBUG // needs debug connection features
......@@ -42,7 +42,7 @@ public void MultipleEndpointsThrowAggregateException()
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<AggregateException>(ex.InnerException);
var aggException = (AggregateException)ex.InnerException;
......@@ -70,7 +70,7 @@ public void NullInnerExceptionForMultipleEndpointsWithNoLastException()
var conn = muxer.GetDatabase();
muxer.AllowConnect = false;
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.Null(ex.InnerException);
}
......@@ -95,7 +95,7 @@ public void ServerTakesPrecendenceOverSnapshot()
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<Exception>(ex.InnerException);
Assert.That(muxer.GetServerSnapshot()[0].LastException, Is.EqualTo(ex.InnerException));
......
......@@ -351,7 +351,7 @@ internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options
if (server == null) throw new ArgumentNullException(nameof(server));
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;
CommandMap.AssertAvailable(RedisCommand.SLAVEOF);
......@@ -935,6 +935,7 @@ private ConnectionMultiplexer(ConfigurationOptions configuration)
{
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
IncludeDetailInExceptions = true;
IncludePerformanceCountersInExceptions = false;
this.configuration = configuration;
......@@ -1964,7 +1965,7 @@ internal Task<T> ExecuteAsyncImpl<T>(Message message, ResultProcessor<T> process
var source = ResultBox<T>.Get(tcs);
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;
}
......@@ -2005,7 +2006,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
{
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))
......@@ -2068,7 +2069,10 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
add("ThreadPool-Workers", "WORKER", worker);
data.Add(Tuple.Create("Busy-Workers", busyWorkerCount.ToString()));
if (IncludePerformanceCountersInExceptions)
{
add("Local-CPU", "Local-CPU", GetSystemCpuPercent());
}
#endif
sb.Append(" (Please take a look at this article for some common client-side issues that can cause timeouts: ");
sb.Append(timeoutHelpLink);
......@@ -2106,11 +2110,11 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
}
#if !CORE_CLR
internal static string GetThreadPoolAndCPUSummary()
internal static string GetThreadPoolAndCPUSummary(bool includePerformanceCounters)
{
string iocp, worker;
GetThreadPoolStats(out iocp, out worker);
var cpu = GetSystemCpuPercent();
var cpu = includePerformanceCounters ? GetSystemCpuPercent() : "n/a";
return $"IOCP: {iocp}, WORKER: {worker}, Local-CPU: {cpu}";
}
......@@ -2152,6 +2156,11 @@ private static int GetThreadPoolStats(out string iocp, out string worker)
/// </summary>
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;
string stormLogSnapshot;
/// <summary>
......
......@@ -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);
......@@ -115,7 +115,7 @@ internal static Exception NoConnectionAvailable(bool includeDetail, RedisCommand
#if !CORE_CLR
if (includeDetail)
{
exceptionmessage.Append("; ").Append(ConnectionMultiplexer.GetThreadPoolAndCPUSummary());
exceptionmessage.Append("; ").Append(ConnectionMultiplexer.GetThreadPoolAndCPUSummary(includePerformanceCounters));
}
#endif
......
......@@ -266,7 +266,7 @@ internal void KeepAlive()
Multiplexer.Trace("Enqueue: " + msg);
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()
if (server == null)
{
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);
if (bridge == null)
{
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
......
......@@ -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
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 base.ExecuteAsync<T>(message, processor, server);
......@@ -566,7 +566,7 @@ internal override T ExecuteSync<T>(Message message, ResultProcessor<T> processor
if (!server.IsConnected)
{
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);
}
......
......@@ -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);
#if !CORE_CLR
err += ConnectionMultiplexer.GetThreadPoolAndCPUSummary();
err += ConnectionMultiplexer.GetThreadPoolAndCPUSummary(bridge.Multiplexer.IncludePerformanceCountersInExceptions);
#endif
}
}
......
......@@ -564,7 +564,7 @@ internal Task<T> QueueDirectAsync<T>(Message message, ResultProcessor<T> process
if (bridge == null) bridge = GetBridge(message.Command);
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;
}
......
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