New: All setting values are cached for better responsiveness.

pull/2/head
kay.one 13 years ago
parent 2051c9d911
commit 6df184b7cb

@ -1,7 +1,9 @@
using System;
using System.IO;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Test.Common;
using PetaPoco;
@ -60,5 +62,11 @@ namespace NzbDrone.Core.Test.Framework
return new ProgressNotification("Mock notification");
}
}
[TearDown]
public void CoreTestTearDown()
{
ConfigProvider.ClearCache();
}
}
}

@ -113,6 +113,7 @@
<Compile Include="JobTests\BannerDownloadJobTest.cs" />
<Compile Include="JobTests\RecentBacklogSearchJobTest.cs" />
<Compile Include="ProviderTests\AnalyticsProviderTests\AnalyticsProviderFixture.cs" />
<Compile Include="ProviderTests\ConfigProviderTests\ConfigCachingFixture.cs" />
<Compile Include="ProviderTests\DecisionEngineTests\QualityAllowedByProfileSpecificationFixtrue.cs" />
<Compile Include="ProviderTests\DecisionEngineTests\UpgradeHistorySpecificationFixtrue.cs" />
<Compile Include="ProviderTests\DecisionEngineTests\UpgradeDiskSpecificationFixtrue.cs" />
@ -172,7 +173,7 @@
<Compile Include="ProviderTests\IndexerProviderTest.cs" />
<Compile Include="ProviderTests\HistoryProviderTest.cs" />
<Compile Include="ProviderTests\MediaFileProviderTest.cs" />
<Compile Include="ProviderTests\ConfigProviderTest.cs" />
<Compile Include="ProviderTests\ConfigProviderTests\ConfigProviderFixture.cs" />
<Compile Include="ProviderTests\EpisodeProviderTest.cs" />
<Compile Include="Framework\TestDbHelper.cs" />
<Compile Include="ParserTest.cs" />

@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Test.Framework;
using PetaPoco;
namespace NzbDrone.Core.Test.ProviderTests.ConfigProviderTests
{
[TestFixture]
public class ConfigCachingFixture : CoreTest
{
[SetUp]
public void Setup()
{
Mocker.GetMock<IDatabase>().Setup(c => c.Fetch<Config>())
.Returns(new List<Config> { new Config { Key = "Key1", Value = "Value1" } });
}
[Test]
public void getting_value_more_than_once_should_hit_db_once()
{
Mocker.Resolve<ConfigProvider>().GetValue("Key1", null).Should().Be("Value1");
Mocker.Resolve<ConfigProvider>().GetValue("Key1", null).Should().Be("Value1");
Mocker.Resolve<ConfigProvider>().GetValue("Key1", null).Should().Be("Value1");
Mocker.GetMock<IDatabase>().Verify(c => c.Fetch<Config>(), Times.Once());
}
}
}

@ -6,11 +6,11 @@ using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests
namespace NzbDrone.Core.Test.ProviderTests.ConfigProviderTests
{
[TestFixture]
// ReSharper disable InconsistentNaming
public class ConfigProviderTest : CoreTest
public class ConfigProviderFixture : CoreTest
{
[SetUp]
public void SetUp()
@ -134,6 +134,15 @@ namespace NzbDrone.Core.Test.ProviderTests
guid.Should().NotBeEmpty();
}
[Test]
public void updating_a_vakye_should_update_its_value()
{
Mocker.Resolve<ConfigProvider>().SabHost = "Test";
Mocker.Resolve<ConfigProvider>().SabHost.Should().Be("Test");
Mocker.Resolve<ConfigProvider>().SabHost = "Test2";
Mocker.Resolve<ConfigProvider>().SabHost.Should().Be("Test2");
}
[Test]
[Description("This test will use reflection to ensure each config property read/writes to a unique key")]

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Ninject;
using NLog;
using NzbDrone.Core.Model;
@ -11,7 +12,10 @@ namespace NzbDrone.Core.Providers.Core
{
public class ConfigProvider
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private static Dictionary<string, string> cache = new Dictionary<string, string>();
private readonly IDatabase _database;
[Inject]
@ -24,7 +28,7 @@ namespace NzbDrone.Core.Providers.Core
{
}
public IList<Config> All()
public IEnumerable<Config> All()
{
return _database.Fetch<Config>();
}
@ -449,12 +453,15 @@ namespace NzbDrone.Core.Providers.Core
public virtual string GetValue(string key, object defaultValue, bool persist = false)
{
var dbValue = _database.SingleOrDefault<Config>("WHERE [Key] =@0", key);
EnsureCache();
if (dbValue != null && !String.IsNullOrEmpty(dbValue.Value))
return dbValue.Value;
string dbValue;
Logger.Trace("Unable to find config key '{0}' defaultValue:'{1}'", key, defaultValue);
if (cache.TryGetValue(key, out dbValue) && dbValue != null && !String.IsNullOrEmpty(dbValue))
return dbValue;
logger.Trace("Unable to find config key '{0}' defaultValue:'{1}'", key, defaultValue);
if (persist)
SetValue(key, defaultValue.ToString());
@ -479,7 +486,7 @@ namespace NzbDrone.Core.Providers.Core
if (value == null)
throw new ArgumentNullException("key");
Logger.Trace("Writing Setting to file. Key:'{0}' Value:'{1}'", key, value);
logger.Trace("Writing Setting to file. Key:'{0}' Value:'{1}'", key, value);
var dbValue = _database.SingleOrDefault<Config>("WHERE [KEY]=@0", key);
@ -490,11 +497,28 @@ namespace NzbDrone.Core.Providers.Core
else
{
dbValue.Value = value;
using (var tran = _database.GetTransaction())
{
_database.Update(dbValue);
tran.Complete();
}
ClearCache();
}
private void EnsureCache()
{
lock (cache)
{
if (!cache.Any())
{
cache = _database.Fetch<Config>().ToDictionary(c => c.Key, c => c.Value);
}
}
}
public static void ClearCache()
{
lock (cache)
{
cache = new Dictionary<string, string>();
}
}
}

@ -84,8 +84,8 @@ namespace NzbDrone.Web.Controllers
return Json(new
{
iTotalRecords = config.Count,
iTotalDisplayRecords = config.Count,
iTotalRecords = config.Count(),
iTotalDisplayRecords = config.Count(),
aaData = config
}, JsonRequestBehavior.AllowGet);
}

Loading…
Cancel
Save