From cf371a4e740aa8ca76d49027e13d3dfa38ce3bdb Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Tue, 16 Jan 2018 18:11:11 -0800 Subject: [PATCH] Disable heartbeat warning when debugger is attached (#2258) --- .../Internal/Infrastructure/Heartbeat.cs | 9 +++-- src/Kestrel.Core/KestrelServer.cs | 5 ++- .../DateHeaderValueManagerTests.cs | 6 ++-- test/Kestrel.Core.Tests/HeartbeatTests.cs | 33 +++++++++++++++++-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/Kestrel.Core/Internal/Infrastructure/Heartbeat.cs b/src/Kestrel.Core/Internal/Infrastructure/Heartbeat.cs index 28a11f5580..f722f60e9d 100644 --- a/src/Kestrel.Core/Internal/Infrastructure/Heartbeat.cs +++ b/src/Kestrel.Core/Internal/Infrastructure/Heartbeat.cs @@ -13,14 +13,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure private readonly IHeartbeatHandler[] _callbacks; private readonly ISystemClock _systemClock; + private readonly IDebugger _debugger; private readonly IKestrelTrace _trace; private Timer _timer; private int _executingOnHeartbeat; - public Heartbeat(IHeartbeatHandler[] callbacks, ISystemClock systemClock, IKestrelTrace trace) + public Heartbeat(IHeartbeatHandler[] callbacks, ISystemClock systemClock, IDebugger debugger, IKestrelTrace trace) { _callbacks = callbacks; _systemClock = systemClock; + _debugger = debugger; _trace = trace; } @@ -59,7 +61,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure } else { - _trace.HeartbeatSlow(Interval, now); + if (!_debugger.IsAttached) + { + _trace.HeartbeatSlow(Interval, now); + } } } diff --git a/src/Kestrel.Core/KestrelServer.cs b/src/Kestrel.Core/KestrelServer.cs index 6d2c1d059c..8f1c62099e 100644 --- a/src/Kestrel.Core/KestrelServer.cs +++ b/src/Kestrel.Core/KestrelServer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting.Server; @@ -47,7 +48,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core var httpHeartbeatManager = new HttpHeartbeatManager(serviceContext.ConnectionManager); _heartbeat = new Heartbeat( new IHeartbeatHandler[] { serviceContext.DateHeaderValueManager, httpHeartbeatManager }, - serviceContext.SystemClock, Trace); + serviceContext.SystemClock, + DebuggerWrapper.Singleton, + Trace); Features = new FeatureCollection(); _serverAddresses = new ServerAddressesFeature(); diff --git a/test/Kestrel.Core.Tests/DateHeaderValueManagerTests.cs b/test/Kestrel.Core.Tests/DateHeaderValueManagerTests.cs index 8af56589f8..3d1e880765 100644 --- a/test/Kestrel.Core.Tests/DateHeaderValueManagerTests.cs +++ b/test/Kestrel.Core.Tests/DateHeaderValueManagerTests.cs @@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var dateHeaderValueManager = new DateHeaderValueManager(systemClock); var testKestrelTrace = new TestKestrelTrace(); - using (var heartbeat = new Heartbeat(new IHeartbeatHandler[] { dateHeaderValueManager }, systemClock, testKestrelTrace)) + using (var heartbeat = new Heartbeat(new IHeartbeatHandler[] { dateHeaderValueManager }, systemClock, DebuggerWrapper.Singleton, testKestrelTrace)) { Assert.Equal(now.ToString(Rfc1123DateFormat), dateHeaderValueManager.GetDateHeaderValues().String); systemClock.UtcNow = future; @@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var mockHeartbeatHandler = new Mock(); - using (var heartbeat = new Heartbeat(new[] { dateHeaderValueManager, mockHeartbeatHandler.Object }, systemClock, testKestrelTrace)) + using (var heartbeat = new Heartbeat(new[] { dateHeaderValueManager, mockHeartbeatHandler.Object }, systemClock, DebuggerWrapper.Singleton, testKestrelTrace)) { heartbeat.OnHeartbeat(); @@ -100,7 +100,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var dateHeaderValueManager = new DateHeaderValueManager(systemClock); var testKestrelTrace = new TestKestrelTrace(); - using (var heatbeat = new Heartbeat(new IHeartbeatHandler[] { dateHeaderValueManager }, systemClock, testKestrelTrace)) + using (var heatbeat = new Heartbeat(new IHeartbeatHandler[] { dateHeaderValueManager }, systemClock, DebuggerWrapper.Singleton, testKestrelTrace)) { heatbeat.OnHeartbeat(); Assert.Equal(now.ToString(Rfc1123DateFormat), dateHeaderValueManager.GetDateHeaderValues().String); diff --git a/test/Kestrel.Core.Tests/HeartbeatTests.cs b/test/Kestrel.Core.Tests/HeartbeatTests.cs index 6cd3b27000..5b961ce7bf 100644 --- a/test/Kestrel.Core.Tests/HeartbeatTests.cs +++ b/test/Kestrel.Core.Tests/HeartbeatTests.cs @@ -26,14 +26,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { var systemClock = new MockSystemClock(); var heartbeatHandler = new Mock(); + var debugger = new Mock(); var kestrelTrace = new Mock(); var handlerMre = new ManualResetEventSlim(); var traceMre = new ManualResetEventSlim(); heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Callback(() => handlerMre.Wait()); + debugger.Setup(d => d.IsAttached).Returns(false); kestrelTrace.Setup(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow)).Callback(() => traceMre.Set()); - using (var heartbeat = new Heartbeat(new[] { heartbeatHandler.Object }, systemClock, kestrelTrace.Object)) + using (var heartbeat = new Heartbeat(new[] { heartbeatHandler.Object }, systemClock, debugger.Object, kestrelTrace.Object)) { Task.Run(() => heartbeat.OnHeartbeat()); Task.Run(() => heartbeat.OnHeartbeat()); @@ -46,6 +48,33 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Once()); } + [Fact] + public void BlockedHeartbeatIsNotLoggedAsErrorIfDebuggerAttached() + { + var systemClock = new MockSystemClock(); + var heartbeatHandler = new Mock(); + var debugger = new Mock(); + var kestrelTrace = new Mock(); + var handlerMre = new ManualResetEventSlim(); + var traceMre = new ManualResetEventSlim(); + + heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Callback(() => handlerMre.Wait()); + debugger.Setup(d => d.IsAttached).Returns(true); + kestrelTrace.Setup(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow)).Callback(() => traceMre.Set()); + + using (var heartbeat = new Heartbeat(new[] { heartbeatHandler.Object }, systemClock, debugger.Object, kestrelTrace.Object)) + { + Task.Run(() => heartbeat.OnHeartbeat()); + Task.Run(() => heartbeat.OnHeartbeat()); + Assert.False(traceMre.Wait(TimeSpan.FromSeconds(10))); + } + + handlerMre.Set(); + + heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once()); + kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Never()); + } + [Fact] public void ExceptionFromHeartbeatHandlerIsLoggedAsError() { @@ -56,7 +85,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests heartbeatHandler.Setup(h => h.OnHeartbeat(systemClock.UtcNow)).Throws(ex); - using (var heartbeat = new Heartbeat(new[] { heartbeatHandler.Object }, systemClock, kestrelTrace)) + using (var heartbeat = new Heartbeat(new[] { heartbeatHandler.Object }, systemClock, DebuggerWrapper.Singleton, kestrelTrace)) { heartbeat.OnHeartbeat(); }