1
0
Fork 0
mirror of https://github.com/Sonarr/Sonarr synced 2025-02-24 23:13:10 +00:00

Fixed: Heavy qbit api load when CDH Remove is disabled and Seeding time has been reached

ref #3108
This commit is contained in:
Taloth Saldono 2019-07-14 11:34:03 +02:00
parent 082c098420
commit d2764cee2a
2 changed files with 86 additions and 11 deletions

View file

@ -556,6 +556,22 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.CanMoveFiles.Should().BeTrue(); item.CanMoveFiles.Should().BeTrue();
} }
[Test]
public void should_not_fetch_details_twice()
{
GivenGlobalSeedLimits(-1, 30);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 20);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse();
item.CanMoveFiles.Should().BeFalse();
var item2 = Subject.GetItems().Single();
Mocker.GetMock<IQBittorrentProxy>()
.Verify(p => p.GetTorrentProperties(It.IsAny<string>(), It.IsAny<QBittorrentSettings>()), Times.Once());
}
[Test] [Test]
public void should_get_category_from_the_category_if_set() public void should_get_category_from_the_category_if_set()
{ {

View file

@ -12,12 +12,20 @@ using FluentValidation.Results;
using System.Net; using System.Net;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.RemotePathMappings; using NzbDrone.Core.RemotePathMappings;
using NzbDrone.Common.Cache;
namespace NzbDrone.Core.Download.Clients.QBittorrent namespace NzbDrone.Core.Download.Clients.QBittorrent
{ {
public class QBittorrent : TorrentClientBase<QBittorrentSettings> public class QBittorrent : TorrentClientBase<QBittorrentSettings>
{ {
private readonly IQBittorrentProxySelector _proxySelector; private readonly IQBittorrentProxySelector _proxySelector;
private readonly ICached<SeedingTimeCacheEntry> _seedingTimeCache;
private class SeedingTimeCacheEntry
{
public DateTime LastFetched { get; set; }
public long SeedingTime { get; set; }
}
public QBittorrent(IQBittorrentProxySelector proxySelector, public QBittorrent(IQBittorrentProxySelector proxySelector,
ITorrentFileInfoReader torrentFileInfoReader, ITorrentFileInfoReader torrentFileInfoReader,
@ -25,10 +33,13 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
IConfigService configService, IConfigService configService,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IRemotePathMappingService remotePathMappingService, IRemotePathMappingService remotePathMappingService,
ICacheManager cacheManager,
Logger logger) Logger logger)
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)
{ {
_proxySelector = proxySelector; _proxySelector = proxySelector;
_seedingTimeCache = cacheManager.GetCache<SeedingTimeCacheEntry>(GetType(), "seedingTime");
} }
private IQBittorrentProxy Proxy => _proxySelector.GetProxy(Settings); private IQBittorrentProxy Proxy => _proxySelector.GetProxy(Settings);
@ -442,23 +453,71 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
if (torrent.Ratio >= config.MaxRatio) return true; if (torrent.Ratio >= config.MaxRatio) return true;
} }
if (torrent.SeedingTimeLimit >= 0) if (HasReachedSeedingTimeLimit(torrent, config)) return true;
{
if (!torrent.SeedingTime.HasValue)
{ return false;
FetchTorrentDetails(torrent);
} }
if (torrent.SeedingTime >= torrent.SeedingTimeLimit) return true; protected bool HasReachedSeedingTimeLimit(QBittorrentTorrent torrent, QBittorrentPreferences config)
{
long seedingTimeLimit;
if (torrent.SeedingTimeLimit >= 0)
{
seedingTimeLimit = torrent.SeedingTimeLimit;
} }
else if (torrent.SeedingTimeLimit == -2 && config.MaxSeedingTimeEnabled) else if (torrent.SeedingTimeLimit == -2 && config.MaxSeedingTimeEnabled)
{ {
if (!torrent.SeedingTime.HasValue) seedingTimeLimit = config.MaxSeedingTime;
}
else
{ {
FetchTorrentDetails(torrent); return false;
} }
if (torrent.SeedingTime >= config.MaxSeedingTime) return true; if (torrent.SeedingTime.HasValue)
{
// SeedingTime can't be available here, but use it if the api starts to provide it.
return torrent.SeedingTime.Value >= seedingTimeLimit;
}
var cacheKey = Settings.Host + Settings.Port + torrent.Hash;
var cacheSeedingTime = _seedingTimeCache.Find(cacheKey);
if (cacheSeedingTime != null)
{
var togo = seedingTimeLimit - cacheSeedingTime.SeedingTime;
var elapsed = (DateTime.UtcNow - cacheSeedingTime.LastFetched).TotalSeconds;
if (togo <= 0)
{
// Already reached the limit, keep the cache alive
_seedingTimeCache.Set(cacheKey, cacheSeedingTime, TimeSpan.FromMinutes(5));
return true;
}
else if (togo > elapsed)
{
// SeedingTime cannot have reached the required value since the last check, preserve the cache
_seedingTimeCache.Set(cacheKey, cacheSeedingTime, TimeSpan.FromMinutes(5));
return false;
}
}
FetchTorrentDetails(torrent);
cacheSeedingTime = new SeedingTimeCacheEntry
{
LastFetched = DateTime.UtcNow,
SeedingTime = torrent.SeedingTime.Value
};
_seedingTimeCache.Set(cacheKey, cacheSeedingTime, TimeSpan.FromMinutes(5));
if (cacheSeedingTime.SeedingTime >= seedingTimeLimit)
{
// Reached the limit, keep the cache alive
return true;
} }
return false; return false;