mirror of https://github.com/lidarr/Lidarr
New: All setting values are cached for better responsiveness.
This commit is contained in:
parent
2051c9d911
commit
6df184b7cb
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Model.Notification;
|
using NzbDrone.Core.Model.Notification;
|
||||||
|
using NzbDrone.Core.Providers.Core;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
using PetaPoco;
|
using PetaPoco;
|
||||||
|
|
||||||
|
@ -60,5 +62,11 @@ namespace NzbDrone.Core.Test.Framework
|
||||||
return new ProgressNotification("Mock notification");
|
return new ProgressNotification("Mock notification");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void CoreTestTearDown()
|
||||||
|
{
|
||||||
|
ConfigProvider.ClearCache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,7 @@
|
||||||
<Compile Include="JobTests\BannerDownloadJobTest.cs" />
|
<Compile Include="JobTests\BannerDownloadJobTest.cs" />
|
||||||
<Compile Include="JobTests\RecentBacklogSearchJobTest.cs" />
|
<Compile Include="JobTests\RecentBacklogSearchJobTest.cs" />
|
||||||
<Compile Include="ProviderTests\AnalyticsProviderTests\AnalyticsProviderFixture.cs" />
|
<Compile Include="ProviderTests\AnalyticsProviderTests\AnalyticsProviderFixture.cs" />
|
||||||
|
<Compile Include="ProviderTests\ConfigProviderTests\ConfigCachingFixture.cs" />
|
||||||
<Compile Include="ProviderTests\DecisionEngineTests\QualityAllowedByProfileSpecificationFixtrue.cs" />
|
<Compile Include="ProviderTests\DecisionEngineTests\QualityAllowedByProfileSpecificationFixtrue.cs" />
|
||||||
<Compile Include="ProviderTests\DecisionEngineTests\UpgradeHistorySpecificationFixtrue.cs" />
|
<Compile Include="ProviderTests\DecisionEngineTests\UpgradeHistorySpecificationFixtrue.cs" />
|
||||||
<Compile Include="ProviderTests\DecisionEngineTests\UpgradeDiskSpecificationFixtrue.cs" />
|
<Compile Include="ProviderTests\DecisionEngineTests\UpgradeDiskSpecificationFixtrue.cs" />
|
||||||
|
@ -172,7 +173,7 @@
|
||||||
<Compile Include="ProviderTests\IndexerProviderTest.cs" />
|
<Compile Include="ProviderTests\IndexerProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\HistoryProviderTest.cs" />
|
<Compile Include="ProviderTests\HistoryProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\MediaFileProviderTest.cs" />
|
<Compile Include="ProviderTests\MediaFileProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\ConfigProviderTest.cs" />
|
<Compile Include="ProviderTests\ConfigProviderTests\ConfigProviderFixture.cs" />
|
||||||
<Compile Include="ProviderTests\EpisodeProviderTest.cs" />
|
<Compile Include="ProviderTests\EpisodeProviderTest.cs" />
|
||||||
<Compile Include="Framework\TestDbHelper.cs" />
|
<Compile Include="Framework\TestDbHelper.cs" />
|
||||||
<Compile Include="ParserTest.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.Repository;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ProviderTests
|
namespace NzbDrone.Core.Test.ProviderTests.ConfigProviderTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
public class ConfigProviderTest : CoreTest
|
public class ConfigProviderFixture : CoreTest
|
||||||
{
|
{
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp()
|
||||||
|
@ -134,6 +134,15 @@ namespace NzbDrone.Core.Test.ProviderTests
|
||||||
guid.Should().NotBeEmpty();
|
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]
|
[Test]
|
||||||
[Description("This test will use reflection to ensure each config property read/writes to a unique key")]
|
[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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Model;
|
using NzbDrone.Core.Model;
|
||||||
|
@ -11,7 +12,10 @@ namespace NzbDrone.Core.Providers.Core
|
||||||
{
|
{
|
||||||
public class ConfigProvider
|
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;
|
private readonly IDatabase _database;
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
|
@ -24,7 +28,7 @@ namespace NzbDrone.Core.Providers.Core
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<Config> All()
|
public IEnumerable<Config> All()
|
||||||
{
|
{
|
||||||
return _database.Fetch<Config>();
|
return _database.Fetch<Config>();
|
||||||
}
|
}
|
||||||
|
@ -409,7 +413,7 @@ namespace NzbDrone.Core.Providers.Core
|
||||||
set { SetValue("AutoIgnorePreviouslyDownloadedEpisodes", value); }
|
set { SetValue("AutoIgnorePreviouslyDownloadedEpisodes", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Guid UGuid
|
public Guid UGuid
|
||||||
{
|
{
|
||||||
get { return Guid.Parse(GetValue("UGuid", Guid.NewGuid().ToString(), persist: true)); }
|
get { return Guid.Parse(GetValue("UGuid", Guid.NewGuid().ToString(), persist: true)); }
|
||||||
}
|
}
|
||||||
|
@ -449,12 +453,15 @@ namespace NzbDrone.Core.Providers.Core
|
||||||
|
|
||||||
public virtual string GetValue(string key, object defaultValue, bool persist = false)
|
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;
|
|
||||||
|
|
||||||
Logger.Trace("Unable to find config key '{0}' defaultValue:'{1}'", key, defaultValue);
|
string dbValue;
|
||||||
|
|
||||||
|
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)
|
if (persist)
|
||||||
SetValue(key, defaultValue.ToString());
|
SetValue(key, defaultValue.ToString());
|
||||||
|
@ -479,7 +486,7 @@ namespace NzbDrone.Core.Providers.Core
|
||||||
if (value == null)
|
if (value == null)
|
||||||
throw new ArgumentNullException("key");
|
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);
|
var dbValue = _database.SingleOrDefault<Config>("WHERE [KEY]=@0", key);
|
||||||
|
|
||||||
|
@ -490,12 +497,29 @@ namespace NzbDrone.Core.Providers.Core
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dbValue.Value = value;
|
dbValue.Value = value;
|
||||||
using (var tran = _database.GetTransaction())
|
_database.Update(dbValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnsureCache()
|
||||||
|
{
|
||||||
|
lock (cache)
|
||||||
|
{
|
||||||
|
if (!cache.Any())
|
||||||
{
|
{
|
||||||
_database.Update(dbValue);
|
cache = _database.Fetch<Config>().ToDictionary(c => c.Key, c => c.Value);
|
||||||
tran.Complete();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ClearCache()
|
||||||
|
{
|
||||||
|
lock (cache)
|
||||||
|
{
|
||||||
|
cache = new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,13 +48,13 @@ namespace NzbDrone.Web.Controllers
|
||||||
|
|
||||||
var jobs = _jobProvider.All().Select(j => new JobModel
|
var jobs = _jobProvider.All().Select(j => new JobModel
|
||||||
{
|
{
|
||||||
Id = j.Id,
|
Id = j.Id,
|
||||||
Enable = j.Enable,
|
Enable = j.Enable,
|
||||||
TypeName = j.TypeName,
|
TypeName = j.TypeName,
|
||||||
Name = j.Name,
|
Name = j.Name,
|
||||||
Interval = j.Interval,
|
Interval = j.Interval,
|
||||||
LastExecution = j.LastExecution.ToString(),
|
LastExecution = j.LastExecution.ToString(),
|
||||||
Success = j.Success
|
Success = j.Success
|
||||||
}).OrderBy(j => j.Interval);
|
}).OrderBy(j => j.Interval);
|
||||||
|
|
||||||
var serializedJobs = new JavaScriptSerializer().Serialize(jobs);
|
var serializedJobs = new JavaScriptSerializer().Serialize(jobs);
|
||||||
|
@ -84,9 +84,9 @@ namespace NzbDrone.Web.Controllers
|
||||||
|
|
||||||
return Json(new
|
return Json(new
|
||||||
{
|
{
|
||||||
iTotalRecords = config.Count,
|
iTotalRecords = config.Count(),
|
||||||
iTotalDisplayRecords = config.Count,
|
iTotalDisplayRecords = config.Count(),
|
||||||
aaData = config
|
aaData = config
|
||||||
}, JsonRequestBehavior.AllowGet);
|
}, JsonRequestBehavior.AllowGet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue