From 958153be556b3ed8cefbdf40b04f02ca6bcdb057 Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Sat, 11 Jun 2016 00:25:59 +0200 Subject: [PATCH] Fixed: Reduced spurious cpu usage on mono while idle. --- .../Instrumentation/DatabaseTarget.cs | 6 ++- .../SlowRunningAsyncTargetWrapper.cs | 51 +++++++++++++++++++ src/NzbDrone.Core/NzbDrone.Core.csproj | 1 + 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/NzbDrone.Core/Instrumentation/SlowRunningAsyncTargetWrapper.cs diff --git a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs index 0fe6c4a63..a2e36a757 100644 --- a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs +++ b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs @@ -28,9 +28,11 @@ namespace NzbDrone.Core.Instrumentation public void Register() { - Rule = new LoggingRule("*", LogLevel.Info, this); + var target = new SlowRunningAsyncTargetWrapper(this) { TimeToSleepBetweenBatches = 500 }; - LogManager.Configuration.AddTarget("DbLogger", new AsyncTargetWrapper(this)); + Rule = new LoggingRule("*", LogLevel.Info, target); + + LogManager.Configuration.AddTarget("DbLogger", target); LogManager.Configuration.LoggingRules.Add(Rule); LogManager.ConfigurationReloaded += OnLogManagerOnConfigurationReloaded; LogManager.ReconfigExistingLoggers(); diff --git a/src/NzbDrone.Core/Instrumentation/SlowRunningAsyncTargetWrapper.cs b/src/NzbDrone.Core/Instrumentation/SlowRunningAsyncTargetWrapper.cs new file mode 100644 index 000000000..0998e0260 --- /dev/null +++ b/src/NzbDrone.Core/Instrumentation/SlowRunningAsyncTargetWrapper.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using NLog.Common; +using NLog.Targets; +using NLog.Targets.Wrappers; + +namespace NzbDrone.Core.Instrumentation +{ + [Target("SlowRunningAsyncTargetWrapper", IsWrapper = true)] + public class SlowRunningAsyncTargetWrapper : AsyncTargetWrapper + { + private int _state; // 0 = idle, 1 = timer active, 2 = timer active + possibly more work + + public SlowRunningAsyncTargetWrapper(Target wrappedTarget) + : base(wrappedTarget) + { + + } + + protected override void StopLazyWriterThread() + { + if (Interlocked.Exchange(ref _state, 0) > 0) + { + base.StopLazyWriterThread(); + } + } + + protected override void Write(AsyncLogEventInfo logEvent) + { + base.Write(logEvent); + + if (Interlocked.Exchange(ref _state, 2) <= 0) + { // Timer was idle. Starting. + base.StartLazyWriterTimer(); + } + } + + protected override void StartLazyWriterTimer() + { + // Is executed when the background task has finished processing the queue. (also executed by base.InitializeTarget once) + + if (Interlocked.Decrement(ref _state) == 1) + { // There might be more work. Restart timer. + base.StartLazyWriterTimer(); + } + } + } +} diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 6a783eda4..672a17623 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -641,6 +641,7 @@ +