mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-04 10:02:40 +01:00
Added Status refreshes to Download Monitoring Service and allow DownloadService to report success (but not failure).
This commit is contained in:
parent
f335cc1af8
commit
4e10d30cf6
@ -57,13 +57,6 @@ public void should_not_return_error_when_no_indexers()
|
||||
{
|
||||
Subject.Check().ShouldBeOk();
|
||||
}
|
||||
[Test]
|
||||
public void should_not_return_error_when_indexer_failed_less_than_an_hour()
|
||||
{
|
||||
GivenIndexer(1, 0.1, 0.5);
|
||||
|
||||
Subject.Check().ShouldBeOk();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_warning_if_indexer_unavailable()
|
||||
|
@ -41,21 +41,6 @@ private void VerifyNoUpdate()
|
||||
.Verify(v => v.Upsert(It.IsAny<IndexerStatus>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_start_backoff_on_first_failure()
|
||||
{
|
||||
WithStatus(new IndexerStatus());
|
||||
|
||||
Subject.RecordFailure(1);
|
||||
|
||||
VerifyUpdate();
|
||||
|
||||
var status = Subject.GetBlockedProviders().FirstOrDefault();
|
||||
status.Should().NotBeNull();
|
||||
status.DisabledTill.Should().HaveValue();
|
||||
status.DisabledTill.Value.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(5), 500);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_cancel_backoff_on_success()
|
||||
{
|
||||
@ -78,20 +63,5 @@ public void should_not_store_update_if_already_okay()
|
||||
|
||||
VerifyNoUpdate();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_preserve_escalation_on_intermittent_success()
|
||||
{
|
||||
WithStatus(new IndexerStatus { MostRecentFailure = _epoch - TimeSpan.FromSeconds(4), EscalationLevel = 3 });
|
||||
|
||||
Subject.RecordSuccess(1);
|
||||
Subject.RecordSuccess(1);
|
||||
Subject.RecordFailure(1);
|
||||
|
||||
var status = Subject.GetBlockedProviders().FirstOrDefault();
|
||||
status.Should().NotBeNull();
|
||||
status.DisabledTill.Should().HaveValue();
|
||||
status.DisabledTill.Value.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(15), 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Composition;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
@ -9,17 +11,24 @@ namespace NzbDrone.Core.Download
|
||||
{
|
||||
public interface IDownloadClientFactory : IProviderFactory<IDownloadClient, DownloadClientDefinition>
|
||||
{
|
||||
|
||||
List<IDownloadClient> DownloadHandlingEnabled(bool filterBlockedClients = true);
|
||||
}
|
||||
|
||||
public class DownloadClientFactory : ProviderFactory<IDownloadClient, DownloadClientDefinition>, IDownloadClientFactory
|
||||
{
|
||||
private readonly IDownloadClientRepository _providerRepository;
|
||||
private readonly IDownloadClientStatusService _downloadClientStatusService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public DownloadClientFactory(IDownloadClientRepository providerRepository, IEnumerable<IDownloadClient> providers, IContainer container, IEventAggregator eventAggregator, Logger logger)
|
||||
public DownloadClientFactory(IDownloadClientStatusService downloadClientStatusService,
|
||||
IDownloadClientRepository providerRepository,
|
||||
IEnumerable<IDownloadClient> providers,
|
||||
IContainer container,
|
||||
IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
: base(providerRepository, providers, container, eventAggregator, logger)
|
||||
{
|
||||
_providerRepository = providerRepository;
|
||||
_downloadClientStatusService = downloadClientStatusService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
protected override List<DownloadClientDefinition> Active()
|
||||
@ -33,5 +42,46 @@ public override void SetProviderCharacteristics(IDownloadClient provider, Downlo
|
||||
|
||||
definition.Protocol = provider.Protocol;
|
||||
}
|
||||
|
||||
public List<IDownloadClient> DownloadHandlingEnabled(bool filterBlockedClients = true)
|
||||
{
|
||||
var enabledClients = GetAvailableProviders();
|
||||
|
||||
if (filterBlockedClients)
|
||||
{
|
||||
return FilterBlockedClients(enabledClients).ToList();
|
||||
}
|
||||
|
||||
return enabledClients.ToList();
|
||||
}
|
||||
|
||||
private IEnumerable<IDownloadClient> FilterBlockedClients(IEnumerable<IDownloadClient> clients)
|
||||
{
|
||||
var blockedIndexers = _downloadClientStatusService.GetBlockedProviders().ToDictionary(v => v.ProviderId, v => v);
|
||||
|
||||
foreach (var client in clients)
|
||||
{
|
||||
DownloadClientStatus downloadClientStatus;
|
||||
if (blockedIndexers.TryGetValue(client.Definition.Id, out downloadClientStatus))
|
||||
{
|
||||
_logger.Debug("Temporarily ignoring download client {0} till {1} due to recent failures.", client.Definition.Name, downloadClientStatus.DisabledTill.Value.ToLocalTime());
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return client;
|
||||
}
|
||||
}
|
||||
|
||||
public override ValidationResult Test(DownloadClientDefinition definition)
|
||||
{
|
||||
var result = base.Test(definition);
|
||||
|
||||
if (result == null && definition.Id != 0)
|
||||
{
|
||||
_downloadClientStatusService.RecordSuccess(definition.Id);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -27,19 +27,12 @@ public IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol)
|
||||
|
||||
public IEnumerable<IDownloadClient> GetDownloadClients()
|
||||
{
|
||||
return _downloadClientFactory.GetAvailableProviders();//.Select(MapDownloadClient);
|
||||
return _downloadClientFactory.GetAvailableProviders();
|
||||
}
|
||||
|
||||
public IDownloadClient Get(int id)
|
||||
{
|
||||
return _downloadClientFactory.GetAvailableProviders().Single(d => d.Definition.Id == id);
|
||||
}
|
||||
|
||||
public IDownloadClient MapDownloadClient(IDownloadClient downloadClient)
|
||||
{
|
||||
_downloadClientFactory.SetProviderCharacteristics(downloadClient, (DownloadClientDefinition)downloadClient.Definition);
|
||||
|
||||
return downloadClient;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,18 +21,21 @@ public interface IDownloadService
|
||||
public class DownloadService : IDownloadService
|
||||
{
|
||||
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||
private readonly IDownloadClientStatusService _downloadClientStatusService;
|
||||
private readonly IIndexerStatusService _indexerStatusService;
|
||||
private readonly IRateLimitService _rateLimitService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public DownloadService(IProvideDownloadClient downloadClientProvider,
|
||||
IIndexerStatusService indexerStatusService,
|
||||
IRateLimitService rateLimitService,
|
||||
IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
IDownloadClientStatusService downloadClientStatusService,
|
||||
IIndexerStatusService indexerStatusService,
|
||||
IRateLimitService rateLimitService,
|
||||
IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
{
|
||||
_downloadClientProvider = downloadClientProvider;
|
||||
_downloadClientStatusService = downloadClientStatusService;
|
||||
_indexerStatusService = indexerStatusService;
|
||||
_rateLimitService = rateLimitService;
|
||||
_eventAggregator = eventAggregator;
|
||||
@ -64,6 +67,7 @@ public void DownloadReport(RemoteEpisode remoteEpisode)
|
||||
try
|
||||
{
|
||||
downloadClientId = downloadClient.Download(remoteEpisode);
|
||||
_downloadClientStatusService.RecordSuccess(downloadClient.Definition.Id);
|
||||
_indexerStatusService.RecordSuccess(remoteEpisode.Release.IndexerId);
|
||||
}
|
||||
catch (ReleaseDownloadException ex)
|
||||
|
@ -15,7 +15,8 @@ public class DownloadMonitoringService : IExecute<CheckForFinishedDownloadComman
|
||||
IHandle<EpisodeGrabbedEvent>,
|
||||
IHandle<EpisodeImportedEvent>
|
||||
{
|
||||
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||
private readonly IDownloadClientStatusService _downloadClientStatusService;
|
||||
private readonly IDownloadClientFactory _downloadClientFactory;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IManageCommandQueue _manageCommandQueue;
|
||||
private readonly IConfigService _configService;
|
||||
@ -25,16 +26,18 @@ public class DownloadMonitoringService : IExecute<CheckForFinishedDownloadComman
|
||||
private readonly Logger _logger;
|
||||
private readonly Debouncer _refreshDebounce;
|
||||
|
||||
public DownloadMonitoringService(IProvideDownloadClient downloadClientProvider,
|
||||
IEventAggregator eventAggregator,
|
||||
IManageCommandQueue manageCommandQueue,
|
||||
IConfigService configService,
|
||||
IFailedDownloadService failedDownloadService,
|
||||
ICompletedDownloadService completedDownloadService,
|
||||
ITrackedDownloadService trackedDownloadService,
|
||||
Logger logger)
|
||||
public DownloadMonitoringService(IDownloadClientStatusService downloadClientStatusService,
|
||||
IDownloadClientFactory downloadClientFactory,
|
||||
IEventAggregator eventAggregator,
|
||||
IManageCommandQueue manageCommandQueue,
|
||||
IConfigService configService,
|
||||
IFailedDownloadService failedDownloadService,
|
||||
ICompletedDownloadService completedDownloadService,
|
||||
ITrackedDownloadService trackedDownloadService,
|
||||
Logger logger)
|
||||
{
|
||||
_downloadClientProvider = downloadClientProvider;
|
||||
_downloadClientStatusService = downloadClientStatusService;
|
||||
_downloadClientFactory = downloadClientFactory;
|
||||
_eventAggregator = eventAggregator;
|
||||
_manageCommandQueue = manageCommandQueue;
|
||||
_configService = configService;
|
||||
@ -56,7 +59,7 @@ private void Refresh()
|
||||
_refreshDebounce.Pause();
|
||||
try
|
||||
{
|
||||
var downloadClients = _downloadClientProvider.GetDownloadClients();
|
||||
var downloadClients = _downloadClientFactory.DownloadHandlingEnabled();
|
||||
|
||||
var trackedDownloads = new List<TrackedDownload>();
|
||||
|
||||
@ -84,9 +87,12 @@ private List<TrackedDownload> ProcessClientDownloads(IDownloadClient downloadCli
|
||||
try
|
||||
{
|
||||
downloadClientHistory = downloadClient.GetItems().ToList();
|
||||
|
||||
_downloadClientStatusService.RecordSuccess(downloadClient.Definition.Id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_downloadClientStatusService.RecordFailure(downloadClient.Definition.Id);
|
||||
_logger.Warn(ex, "Unable to retrieve queue and history items from " + downloadClient.Definition.Name);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ public override HealthCheck Check()
|
||||
_logger.Debug(ex, "Unable to communicate with {0}", downloadClient.Definition.Name);
|
||||
|
||||
var message = $"Unable to communicate with {downloadClient.Definition.Name}.";
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Error, $"{message} {ex.Message}");
|
||||
return new HealthCheck(GetType(), HealthCheckResult.Error, $"{message} {ex.Message}", "#unable-to-communicate-with-download-client");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ public override HealthCheck Check()
|
||||
i => i.Definition.Id,
|
||||
s => s.ProviderId,
|
||||
(i, s) => new { Provider = i, Status = s })
|
||||
.Where(v => (v.Status.MostRecentFailure - v.Status.InitialFailure) > TimeSpan.FromHours(1))
|
||||
.ToList();
|
||||
|
||||
if (backOffProviders.Empty())
|
||||
|
@ -35,7 +35,7 @@ public override HealthCheck Check()
|
||||
Status = v.GetStatus()
|
||||
}).ToList();
|
||||
}
|
||||
catch (DownloadClientException)
|
||||
catch (Exception)
|
||||
{
|
||||
// One or more download clients failed, assume the health is okay and verify later
|
||||
return new HealthCheck(GetType());
|
||||
|
@ -23,7 +23,6 @@ public override HealthCheck Check()
|
||||
i => i.Definition.Id,
|
||||
s => s.ProviderId,
|
||||
(i, s) => new { Provider = i, Status = s })
|
||||
.Where(v => (v.Status.MostRecentFailure - v.Status.InitialFailure) > TimeSpan.FromHours(1))
|
||||
.ToList();
|
||||
|
||||
if (backOffProviders.Empty())
|
||||
|
Loading…
Reference in New Issue
Block a user