From e304a615d07928865ba511bd361706415d24aeed Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 13 Apr 2015 12:16:47 -0700 Subject: [PATCH] Fixed: DB locking due to Progress Messaging --- .../Instrumentation/DatabaseTarget.cs | 4 ++-- .../ProgressMessageTarget.cs | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs index 66cff3142..b61f217fc 100644 --- a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs +++ b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs @@ -5,6 +5,7 @@ using NLog.Common; using NLog.Config; using NLog; using NLog.Targets; +using NLog.Targets.Wrappers; using NzbDrone.Common.Instrumentation; using NzbDrone.Core.Datastore; using NzbDrone.Core.Lifecycle; @@ -12,7 +13,6 @@ using NzbDrone.Core.Messaging.Events; namespace NzbDrone.Core.Instrumentation { - public class DatabaseTarget : TargetWithLayout, IHandle { private readonly SQLiteConnection _connection; @@ -30,7 +30,7 @@ namespace NzbDrone.Core.Instrumentation { Rule = new LoggingRule("*", LogLevel.Info, this); - LogManager.Configuration.AddTarget("DbLogger", this); + LogManager.Configuration.AddTarget("DbLogger", new AsyncTargetWrapper(this)); LogManager.Configuration.LoggingRules.Add(Rule); LogManager.ConfigurationReloaded += OnLogManagerOnConfigurationReloaded; LogManager.ReconfigExistingLoggers(); diff --git a/src/NzbDrone.Core/ProgressMessaging/ProgressMessageTarget.cs b/src/NzbDrone.Core/ProgressMessaging/ProgressMessageTarget.cs index 2b8d5cff8..a1181c454 100644 --- a/src/NzbDrone.Core/ProgressMessaging/ProgressMessageTarget.cs +++ b/src/NzbDrone.Core/ProgressMessaging/ProgressMessageTarget.cs @@ -2,6 +2,7 @@ using NLog.Config; using NLog; using NLog.Targets; +using NzbDrone.Common.Extensions; using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; @@ -14,6 +15,8 @@ namespace NzbDrone.Core.ProgressMessaging private readonly IManageCommandQueue _commandQueueManager; private static LoggingRule _rule; + private const string REENTRY_LOCK = "ProgressMessagingLock"; + public ProgressMessageTarget(IEventAggregator eventAggregator, IManageCommandQueue commandQueueManager) { _eventAggregator = eventAggregator; @@ -22,6 +25,8 @@ namespace NzbDrone.Core.ProgressMessaging protected override void Write(LogEventInfo logEvent) { + if (!ReentryPreventionCheck()) return; + var command = GetCurrentCommand(); if (IsClientMessage(logEvent, command)) @@ -29,6 +34,8 @@ namespace NzbDrone.Core.ProgressMessaging _commandQueueManager.SetMessage(command, logEvent.FormattedMessage); _eventAggregator.PublishEvent(new CommandUpdatedEvent(command)); } + + MappedDiagnosticsContext.Remove(REENTRY_LOCK); } private CommandModel GetCurrentCommand() @@ -53,6 +60,20 @@ namespace NzbDrone.Core.ProgressMessaging return logEvent.Properties.ContainsKey("Status"); } + private bool ReentryPreventionCheck() + { + var reentryLock = MappedDiagnosticsContext.Get(REENTRY_LOCK); + var commandId = MappedDiagnosticsContext.Get("CommandId"); + + if (reentryLock.IsNullOrWhiteSpace() || reentryLock != commandId) + { + MappedDiagnosticsContext.Set(REENTRY_LOCK, MappedDiagnosticsContext.Get("CommandId")); + return true; + } + + return false; + } + public void Handle(ApplicationStartedEvent message) { _rule = new LoggingRule("*", LogLevel.Trace, this);