mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-04 10:02:40 +01:00
Fixed: Don't purge xem scene mapping cache when new series gets added.
This commit is contained in:
parent
03e2adc332
commit
7818f0c59b
102
src/NzbDrone.Common.Test/CacheTests/CachedDictionaryFixture.cs
Normal file
102
src/NzbDrone.Common.Test/CacheTests/CachedDictionaryFixture.cs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Test.CacheTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class CachedDictionaryFixture
|
||||||
|
{
|
||||||
|
private CachedDictionary<string> _cachedString;
|
||||||
|
private DictionaryWorker _worker;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
_worker = new DictionaryWorker();
|
||||||
|
_cachedString = new CachedDictionary<string>(_worker.GetDict, TimeSpan.FromMilliseconds(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_fetch_on_create()
|
||||||
|
{
|
||||||
|
_worker.HitCount.Should().Be(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_fetch_on_first_call()
|
||||||
|
{
|
||||||
|
var result = _cachedString.Get("Hi");
|
||||||
|
|
||||||
|
_worker.HitCount.Should().Be(1);
|
||||||
|
|
||||||
|
result.Should().Be("Value");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_fetch_once()
|
||||||
|
{
|
||||||
|
var result1 = _cachedString.Get("Hi");
|
||||||
|
var result2 = _cachedString.Get("HitCount");
|
||||||
|
|
||||||
|
_worker.HitCount.Should().Be(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_auto_refresh_after_lifetime()
|
||||||
|
{
|
||||||
|
var result1 = _cachedString.Get("Hi");
|
||||||
|
|
||||||
|
Thread.Sleep(200);
|
||||||
|
|
||||||
|
var result2 = _cachedString.Get("Hi");
|
||||||
|
|
||||||
|
_worker.HitCount.Should().Be(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_refresh_early_if_requested()
|
||||||
|
{
|
||||||
|
var result1 = _cachedString.Get("Hi");
|
||||||
|
|
||||||
|
Thread.Sleep(10);
|
||||||
|
|
||||||
|
_cachedString.RefreshIfExpired(TimeSpan.FromMilliseconds(1));
|
||||||
|
|
||||||
|
var result2 = _cachedString.Get("Hi");
|
||||||
|
|
||||||
|
_worker.HitCount.Should().Be(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_refresh_early_if_not_expired()
|
||||||
|
{
|
||||||
|
var result1 = _cachedString.Get("Hi");
|
||||||
|
|
||||||
|
_cachedString.RefreshIfExpired(TimeSpan.FromMilliseconds(50));
|
||||||
|
|
||||||
|
var result2 = _cachedString.Get("Hi");
|
||||||
|
|
||||||
|
_worker.HitCount.Should().Be(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DictionaryWorker
|
||||||
|
{
|
||||||
|
public int HitCount { get; private set; }
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetDict()
|
||||||
|
{
|
||||||
|
HitCount++;
|
||||||
|
|
||||||
|
var result = new Dictionary<string, string>();
|
||||||
|
result["Hi"] = "Value";
|
||||||
|
result["HitCount"] = "Hit count is " + HitCount;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -66,6 +66,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="CacheTests\CachedDictionaryFixture.cs" />
|
||||||
<Compile Include="CacheTests\CachedFixture.cs" />
|
<Compile Include="CacheTests\CachedFixture.cs" />
|
||||||
<Compile Include="CacheTests\CachedManagerFixture.cs" />
|
<Compile Include="CacheTests\CachedManagerFixture.cs" />
|
||||||
<Compile Include="ConfigFileProviderTest.cs" />
|
<Compile Include="ConfigFileProviderTest.cs" />
|
||||||
|
@ -6,8 +6,9 @@ namespace NzbDrone.Common.Cache
|
|||||||
{
|
{
|
||||||
public interface ICacheManager
|
public interface ICacheManager
|
||||||
{
|
{
|
||||||
ICached<T> GetCache<T>(Type host, string name);
|
|
||||||
ICached<T> GetCache<T>(Type host);
|
ICached<T> GetCache<T>(Type host);
|
||||||
|
ICached<T> GetCache<T>(Type host, string name);
|
||||||
|
ICachedDictionary<T> GetCacheDictionary<T>(Type host, string name, Func<IDictionary<string, T>> fetchFunc = null, TimeSpan? lifeTime = null);
|
||||||
void Clear();
|
void Clear();
|
||||||
ICollection<ICached> Caches { get; }
|
ICollection<ICached> Caches { get; }
|
||||||
}
|
}
|
||||||
@ -22,12 +23,6 @@ public CacheManager()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICached<T> GetCache<T>(Type host)
|
|
||||||
{
|
|
||||||
Ensure.That(host, () => host).IsNotNull();
|
|
||||||
return GetCache<T>(host, host.FullName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_cache.Clear();
|
_cache.Clear();
|
||||||
@ -35,6 +30,12 @@ public void Clear()
|
|||||||
|
|
||||||
public ICollection<ICached> Caches { get { return _cache.Values; } }
|
public ICollection<ICached> Caches { get { return _cache.Values; } }
|
||||||
|
|
||||||
|
public ICached<T> GetCache<T>(Type host)
|
||||||
|
{
|
||||||
|
Ensure.That(host, () => host).IsNotNull();
|
||||||
|
return GetCache<T>(host, host.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
public ICached<T> GetCache<T>(Type host, string name)
|
public ICached<T> GetCache<T>(Type host, string name)
|
||||||
{
|
{
|
||||||
Ensure.That(host, () => host).IsNotNull();
|
Ensure.That(host, () => host).IsNotNull();
|
||||||
@ -42,5 +43,13 @@ public ICached<T> GetCache<T>(Type host, string name)
|
|||||||
|
|
||||||
return (ICached<T>)_cache.Get(host.FullName + "_" + name, () => new Cached<T>());
|
return (ICached<T>)_cache.Get(host.FullName + "_" + name, () => new Cached<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ICachedDictionary<T> GetCacheDictionary<T>(Type host, string name, Func<IDictionary<string, T>> fetchFunc = null, TimeSpan? lifeTime = null)
|
||||||
|
{
|
||||||
|
Ensure.That(host, () => host).IsNotNull();
|
||||||
|
Ensure.That(name, () => name).IsNotNullOrWhiteSpace();
|
||||||
|
|
||||||
|
return (ICachedDictionary<T>)_cache.Get("dict_" + host.FullName + "_" + name, () => new CachedDictionary<T>(fetchFunc, lifeTime));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
137
src/NzbDrone.Common/Cache/CachedDictionary.cs
Normal file
137
src/NzbDrone.Common/Cache/CachedDictionary.cs
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Cache
|
||||||
|
{
|
||||||
|
|
||||||
|
public class CachedDictionary<TValue> : ICachedDictionary<TValue>
|
||||||
|
{
|
||||||
|
private readonly Func<IDictionary<string, TValue>> _fetchFunc;
|
||||||
|
private readonly TimeSpan? _ttl;
|
||||||
|
|
||||||
|
private DateTime _lastRefreshed = DateTime.MinValue;
|
||||||
|
private ConcurrentDictionary<string, TValue> _items = new ConcurrentDictionary<string, TValue>();
|
||||||
|
|
||||||
|
public CachedDictionary(Func<IDictionary<string, TValue>> fetchFunc = null, TimeSpan? ttl = null)
|
||||||
|
{
|
||||||
|
_fetchFunc = fetchFunc;
|
||||||
|
_ttl = ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsExpired(TimeSpan ttl)
|
||||||
|
{
|
||||||
|
return _lastRefreshed.Add(ttl) < DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshIfExpired()
|
||||||
|
{
|
||||||
|
if (_ttl.HasValue && _fetchFunc != null)
|
||||||
|
{
|
||||||
|
RefreshIfExpired(_ttl.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshIfExpired(TimeSpan ttl)
|
||||||
|
{
|
||||||
|
if (IsExpired(ttl))
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
if (_fetchFunc == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Cannot update cache without data source.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Update(_fetchFunc());
|
||||||
|
ExtendTTL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(IDictionary<string, TValue> items)
|
||||||
|
{
|
||||||
|
_items = new ConcurrentDictionary<string, TValue>(items);
|
||||||
|
ExtendTTL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ExtendTTL()
|
||||||
|
{
|
||||||
|
_lastRefreshed = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||||
|
public ICollection<TValue> Values
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
RefreshIfExpired();
|
||||||
|
return _items.Values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
RefreshIfExpired();
|
||||||
|
return _items.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TValue Get(string key)
|
||||||
|
{
|
||||||
|
RefreshIfExpired();
|
||||||
|
|
||||||
|
TValue result;
|
||||||
|
|
||||||
|
if (!_items.TryGetValue(key, out result))
|
||||||
|
{
|
||||||
|
throw new KeyNotFoundException(string.Format("Item {0} not found in cache.", key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TValue Find(string key)
|
||||||
|
{
|
||||||
|
RefreshIfExpired();
|
||||||
|
|
||||||
|
TValue result;
|
||||||
|
|
||||||
|
_items.TryGetValue(key, out result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_items.Clear();
|
||||||
|
_lastRefreshed = DateTime.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearExpired()
|
||||||
|
{
|
||||||
|
if (!_ttl.HasValue)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Checking expiry without ttl not possible.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsExpired(_ttl.Value))
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(string key)
|
||||||
|
{
|
||||||
|
TValue item;
|
||||||
|
_items.TryRemove(key, out item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
src/NzbDrone.Common/Cache/ICachedDictionary.cs
Normal file
18
src/NzbDrone.Common/Cache/ICachedDictionary.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Cache
|
||||||
|
{
|
||||||
|
public interface ICachedDictionary<TValue> : ICached
|
||||||
|
{
|
||||||
|
void RefreshIfExpired();
|
||||||
|
void RefreshIfExpired(TimeSpan ttl);
|
||||||
|
void Refresh();
|
||||||
|
void Update(IDictionary<string, TValue> items);
|
||||||
|
void ExtendTTL();
|
||||||
|
TValue Get(string key);
|
||||||
|
TValue Find(string key);
|
||||||
|
bool IsExpired(TimeSpan ttl);
|
||||||
|
}
|
||||||
|
}
|
@ -28,7 +28,6 @@ public class HttpClient : IHttpClient
|
|||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
private readonly IRateLimitService _rateLimitService;
|
private readonly IRateLimitService _rateLimitService;
|
||||||
private readonly ICached<CookieContainer> _cookieContainerCache;
|
private readonly ICached<CookieContainer> _cookieContainerCache;
|
||||||
private readonly ICached<bool> _curlTLSFallbackCache;
|
|
||||||
private readonly List<IHttpRequestInterceptor> _requestInterceptors;
|
private readonly List<IHttpRequestInterceptor> _requestInterceptors;
|
||||||
private readonly IHttpDispatcher _httpDispatcher;
|
private readonly IHttpDispatcher _httpDispatcher;
|
||||||
|
|
||||||
|
@ -64,7 +64,9 @@
|
|||||||
<Compile Include="ArchiveService.cs" />
|
<Compile Include="ArchiveService.cs" />
|
||||||
<Compile Include="Cache\Cached.cs" />
|
<Compile Include="Cache\Cached.cs" />
|
||||||
<Compile Include="Cache\CacheManager.cs" />
|
<Compile Include="Cache\CacheManager.cs" />
|
||||||
|
<Compile Include="Cache\CachedDictionary.cs" />
|
||||||
<Compile Include="Cache\ICached.cs" />
|
<Compile Include="Cache\ICached.cs" />
|
||||||
|
<Compile Include="Cache\ICachedDictionary.cs" />
|
||||||
<Compile Include="Cloud\CloudClient.cs" />
|
<Compile Include="Cloud\CloudClient.cs" />
|
||||||
<Compile Include="Composition\Container.cs" />
|
<Compile Include="Composition\Container.cs" />
|
||||||
<Compile Include="Composition\ContainerBuilderBase.cs" />
|
<Compile Include="Composition\ContainerBuilderBase.cs" />
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Tv.Events;
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.DataAugmentation.SceneNumbering
|
namespace NzbDrone.Core.Test.DataAugmentation.SceneNumbering
|
||||||
{
|
{
|
||||||
@ -144,6 +145,25 @@ public void should_not_clear_scenenumbering_if_no_results_at_all_from_thexem()
|
|||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
Mocker.GetMock<ISeriesService>()
|
||||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_clear_scenenumbering_if_thexem_throws()
|
||||||
|
{
|
||||||
|
GivenExistingMapping();
|
||||||
|
|
||||||
|
Mocker.GetMock<IXemProxy>()
|
||||||
|
.Setup(v => v.GetXemSeriesIds())
|
||||||
|
.Throws(new InvalidOperationException());
|
||||||
|
|
||||||
|
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||||
|
|
||||||
|
Mocker.GetMock<ISeriesService>()
|
||||||
|
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -28,8 +28,8 @@ public class SceneMappingService : ISceneMappingService,
|
|||||||
private readonly IEnumerable<ISceneMappingProvider> _sceneMappingProviders;
|
private readonly IEnumerable<ISceneMappingProvider> _sceneMappingProviders;
|
||||||
private readonly IEventAggregator _eventAggregator;
|
private readonly IEventAggregator _eventAggregator;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
private readonly ICached<List<SceneMapping>> _getTvdbIdCache;
|
private readonly ICachedDictionary<List<SceneMapping>> _getTvdbIdCache;
|
||||||
private readonly ICached<List<SceneMapping>> _findByTvdbIdCache;
|
private readonly ICachedDictionary<List<SceneMapping>> _findByTvdbIdCache;
|
||||||
|
|
||||||
public SceneMappingService(ISceneMappingRepository repository,
|
public SceneMappingService(ISceneMappingRepository repository,
|
||||||
ICacheManager cacheManager,
|
ICacheManager cacheManager,
|
||||||
@ -40,10 +40,10 @@ public SceneMappingService(ISceneMappingRepository repository,
|
|||||||
_repository = repository;
|
_repository = repository;
|
||||||
_sceneMappingProviders = sceneMappingProviders;
|
_sceneMappingProviders = sceneMappingProviders;
|
||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
|
|
||||||
_getTvdbIdCache = cacheManager.GetCache<List<SceneMapping>>(GetType(), "tvdb_id");
|
|
||||||
_findByTvdbIdCache = cacheManager.GetCache<List<SceneMapping>>(GetType(), "find_tvdb_id");
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
|
_getTvdbIdCache = cacheManager.GetCacheDictionary<List<SceneMapping>>(GetType(), "tvdb_id");
|
||||||
|
_findByTvdbIdCache = cacheManager.GetCacheDictionary<List<SceneMapping>>(GetType(), "find_tvdb_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> GetSceneNames(int tvdbId, IEnumerable<int> seasonNumbers)
|
public List<string> GetSceneNames(int tvdbId, IEnumerable<int> seasonNumbers)
|
||||||
@ -143,6 +143,7 @@ private void UpdateMappings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
RefreshCache();
|
RefreshCache();
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new SceneMappingsUpdatedEvent());
|
_eventAggregator.PublishEvent(new SceneMappingsUpdatedEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,18 +185,8 @@ private void RefreshCache()
|
|||||||
{
|
{
|
||||||
var mappings = _repository.All().ToList();
|
var mappings = _repository.All().ToList();
|
||||||
|
|
||||||
_getTvdbIdCache.Clear();
|
_getTvdbIdCache.Update(mappings.GroupBy(v => v.ParseTerm).ToDictionary(v => v.Key, v => v.ToList()));
|
||||||
_findByTvdbIdCache.Clear();
|
_findByTvdbIdCache.Update(mappings.GroupBy(v => v.TvdbId).ToDictionary(v => v.Key.ToString(), v => v.ToList()));
|
||||||
|
|
||||||
foreach (var sceneMapping in mappings.GroupBy(v => v.ParseTerm))
|
|
||||||
{
|
|
||||||
_getTvdbIdCache.Set(sceneMapping.Key, sceneMapping.ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var sceneMapping in mappings.GroupBy(x => x.TvdbId))
|
|
||||||
{
|
|
||||||
_findByTvdbIdCache.Set(sceneMapping.Key.ToString(), sceneMapping.ToList());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> FilterNonEnglish(List<string> titles)
|
private List<string> FilterNonEnglish(List<string> titles)
|
||||||
@ -205,7 +196,10 @@ private List<string> FilterNonEnglish(List<string> titles)
|
|||||||
|
|
||||||
public void Handle(SeriesRefreshStartingEvent message)
|
public void Handle(SeriesRefreshStartingEvent message)
|
||||||
{
|
{
|
||||||
UpdateMappings();
|
if (message.ManualTrigger && _findByTvdbIdCache.IsExpired(TimeSpan.FromMinutes(1)))
|
||||||
|
{
|
||||||
|
UpdateMappings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(UpdateSceneMappingCommand message)
|
public void Execute(UpdateSceneMappingCommand message)
|
||||||
|
@ -16,7 +16,7 @@ public class XemService : ISceneMappingProvider, IHandle<SeriesUpdatedEvent>, IH
|
|||||||
private readonly IXemProxy _xemProxy;
|
private readonly IXemProxy _xemProxy;
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
private readonly ICached<bool> _cache;
|
private readonly ICachedDictionary<bool> _cache;
|
||||||
|
|
||||||
public XemService(IEpisodeService episodeService,
|
public XemService(IEpisodeService episodeService,
|
||||||
IXemProxy xemProxy,
|
IXemProxy xemProxy,
|
||||||
@ -26,7 +26,7 @@ public XemService(IEpisodeService episodeService,
|
|||||||
_xemProxy = xemProxy;
|
_xemProxy = xemProxy;
|
||||||
_seriesService = seriesService;
|
_seriesService = seriesService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_cache = cacheManager.GetCache<bool>(GetType());
|
_cache = cacheManager.GetCacheDictionary<bool>(GetType(), "mappedTvdbid");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PerformUpdate(Series series)
|
private void PerformUpdate(Series series)
|
||||||
@ -40,7 +40,6 @@ private void PerformUpdate(Series series)
|
|||||||
if (!mappings.Any() && !series.UseSceneNumbering)
|
if (!mappings.Any() && !series.UseSceneNumbering)
|
||||||
{
|
{
|
||||||
_logger.Debug("Mappings for: {0} are empty, skipping", series);
|
_logger.Debug("Mappings for: {0} are empty, skipping", series);
|
||||||
_cache.Remove(series.TvdbId.ToString());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,18 +170,25 @@ private void ExtrapolateMappings(Series series, List<Episode> episodes, List<Mod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshCache()
|
private void UpdateXemSeriesIds()
|
||||||
{
|
{
|
||||||
var ids = _xemProxy.GetXemSeriesIds();
|
try
|
||||||
|
|
||||||
if (ids.Any())
|
|
||||||
{
|
{
|
||||||
_cache.Clear();
|
var ids = _xemProxy.GetXemSeriesIds();
|
||||||
|
|
||||||
|
if (ids.Any())
|
||||||
|
{
|
||||||
|
_cache.Update(ids.ToDictionary(v => v.ToString(), v => true));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cache.ExtendTTL();
|
||||||
|
_logger.Warn("Failed to update Xem series list.");
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
foreach (var id in ids)
|
|
||||||
{
|
{
|
||||||
_cache.Set(id.ToString(), true, TimeSpan.FromHours(1));
|
_cache.ExtendTTL();
|
||||||
|
_logger.Warn(ex, "Failed to update Xem series list.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,9 +212,9 @@ public List<SceneMapping> GetSceneMappings()
|
|||||||
|
|
||||||
public void Handle(SeriesUpdatedEvent message)
|
public void Handle(SeriesUpdatedEvent message)
|
||||||
{
|
{
|
||||||
if (_cache.Count == 0)
|
if (_cache.IsExpired(TimeSpan.FromHours(3)))
|
||||||
{
|
{
|
||||||
RefreshCache();
|
UpdateXemSeriesIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cache.Count == 0)
|
if (_cache.Count == 0)
|
||||||
@ -228,7 +234,10 @@ public void Handle(SeriesUpdatedEvent message)
|
|||||||
|
|
||||||
public void Handle(SeriesRefreshStartingEvent message)
|
public void Handle(SeriesRefreshStartingEvent message)
|
||||||
{
|
{
|
||||||
RefreshCache();
|
if (message.ManualTrigger && _cache.IsExpired(TimeSpan.FromMinutes(1)))
|
||||||
|
{
|
||||||
|
UpdateXemSeriesIds();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,11 @@ namespace NzbDrone.Core.Tv.Events
|
|||||||
{
|
{
|
||||||
public class SeriesRefreshStartingEvent : IEvent
|
public class SeriesRefreshStartingEvent : IEvent
|
||||||
{
|
{
|
||||||
|
public bool ManualTrigger { get; set; }
|
||||||
|
|
||||||
|
public SeriesRefreshStartingEvent(bool manualTrigger)
|
||||||
|
{
|
||||||
|
ManualTrigger = manualTrigger;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -144,7 +144,7 @@ private List<Season> UpdateSeasons(Series series, Series seriesInfo)
|
|||||||
|
|
||||||
public void Execute(RefreshSeriesCommand message)
|
public void Execute(RefreshSeriesCommand message)
|
||||||
{
|
{
|
||||||
_eventAggregator.PublishEvent(new SeriesRefreshStartingEvent());
|
_eventAggregator.PublishEvent(new SeriesRefreshStartingEvent(message.Trigger == CommandTrigger.Manual));
|
||||||
|
|
||||||
if (message.SeriesId.HasValue)
|
if (message.SeriesId.HasValue)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user