diff --git a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs index 74715f438..1cc7d81f7 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs @@ -180,7 +180,7 @@ namespace NzbDrone.Core.Test.Download } [Test] - public void should_not_attempt_download_if_client_isnt_configure() + public void should_not_attempt_download_if_client_isnt_configured() { Assert.Throws(() => Subject.DownloadReport(_parseResult)); @@ -188,6 +188,21 @@ namespace NzbDrone.Core.Test.Download VerifyEventNotPublished(); } + [Test] + public void should_not_attempt_download_if_client_is_disabled() + { + WithUsenetClient(); + + Mocker.GetMock() + .Setup(v => v.IsDisabled(It.IsAny())) + .Returns(true); + + Assert.Throws(() => Subject.DownloadReport(_parseResult)); + + Mocker.GetMock().Verify(c => c.Download(It.IsAny()), Times.Never()); + VerifyEventNotPublished(); + } + [Test] public void should_send_download_to_correct_usenet_client() { diff --git a/src/NzbDrone.Core/Download/DownloadService.cs b/src/NzbDrone.Core/Download/DownloadService.cs index bf73802cf..450836a4a 100644 --- a/src/NzbDrone.Core/Download/DownloadService.cs +++ b/src/NzbDrone.Core/Download/DownloadService.cs @@ -55,6 +55,11 @@ namespace NzbDrone.Core.Download throw new DownloadClientUnavailableException($"{remoteAlbum.Release.DownloadProtocol} Download client isn't configured yet"); } + if (_downloadClientStatusService.IsDisabled(downloadClient.Definition.Id)) + { + throw new DownloadClientUnavailableException($"{downloadClient.Name} is disabled due to recent failues"); + } + // Limit grabs to 2 per second. if (remoteAlbum.Release.DownloadUrl.IsNotNullOrWhiteSpace() && !remoteAlbum.Release.DownloadUrl.StartsWith("magnet:")) { diff --git a/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs b/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs index a83db052d..58089c007 100644 --- a/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs +++ b/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs @@ -10,6 +10,7 @@ namespace NzbDrone.Core.ThingiProvider.Status public interface IProviderStatusServiceBase where TModel : ProviderStatusBase, new() { + bool IsDisabled(int providerId); List GetBlockedProviders(); void RecordSuccess(int providerId); void RecordFailure(int providerId, TimeSpan minimumBackOff = default(TimeSpan)); @@ -37,6 +38,11 @@ namespace NzbDrone.Core.ThingiProvider.Status _logger = logger; } + public bool IsDisabled(int providerId) + { + return GetProviderStatus(providerId).IsDisabled(); + } + public virtual List GetBlockedProviders() { return _providerStatusRepository.All().Where(v => v.IsDisabled()).ToList();