Fixed: Failing Newznab capabilities request should trigger automatic indexer backoff logic.
This commit is contained in:
parent
5613ab05e0
commit
e4c3418987
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
@ -7,6 +8,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Indexers.Newznab;
|
using NzbDrone.Core.Indexers.Newznab;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
|
namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
|
||||||
{
|
{
|
||||||
|
@ -43,7 +45,7 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
|
||||||
Mocker.GetMock<IHttpClient>()
|
Mocker.GetMock<IHttpClient>()
|
||||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
var releases = Subject.FetchRecent();
|
||||||
|
|
||||||
releases.Should().HaveCount(100);
|
releases.Should().HaveCount(100);
|
||||||
|
@ -69,5 +71,27 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
|
||||||
|
|
||||||
Subject.PageSize.Should().Be(25);
|
Subject.PageSize.Should().Be(25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_record_indexer_failure_if_caps_throw()
|
||||||
|
{
|
||||||
|
var request = new HttpRequest("http://my.indexer.com");
|
||||||
|
var response = new HttpResponse(request, new HttpHeader(), new byte[0], (HttpStatusCode)429);
|
||||||
|
response.Headers["Retry-After"] = "300";
|
||||||
|
|
||||||
|
Mocker.GetMock<INewznabCapabilitiesProvider>()
|
||||||
|
.Setup(v => v.GetCapabilities(It.IsAny<NewznabSettings>()))
|
||||||
|
.Throws(new TooManyRequestsException(request, response));
|
||||||
|
|
||||||
|
_caps.MaxPageSize = 30;
|
||||||
|
_caps.DefaultPageSize = 25;
|
||||||
|
|
||||||
|
Subject.FetchRecent().Should().BeEmpty();
|
||||||
|
|
||||||
|
Mocker.GetMock<IIndexerStatusService>()
|
||||||
|
.Verify(v => v.RecordFailure(It.IsAny<int>(), TimeSpan.FromMinutes(5.0)), Times.Once());
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
return new List<ReleaseInfo>();
|
return new List<ReleaseInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var generator = GetRequestGenerator();
|
return FetchReleases(g => g.GetRecentRequests(), true);
|
||||||
|
|
||||||
return FetchReleases(generator.GetRecentRequests(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IList<ReleaseInfo> Fetch(SingleEpisodeSearchCriteria searchCriteria)
|
public override IList<ReleaseInfo> Fetch(SingleEpisodeSearchCriteria searchCriteria)
|
||||||
|
@ -58,9 +56,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
return new List<ReleaseInfo>();
|
return new List<ReleaseInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var generator = GetRequestGenerator();
|
return FetchReleases(g => g.GetSearchRequests(searchCriteria));
|
||||||
|
|
||||||
return FetchReleases(generator.GetSearchRequests(searchCriteria));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IList<ReleaseInfo> Fetch(SeasonSearchCriteria searchCriteria)
|
public override IList<ReleaseInfo> Fetch(SeasonSearchCriteria searchCriteria)
|
||||||
|
@ -70,9 +66,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
return new List<ReleaseInfo>();
|
return new List<ReleaseInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var generator = GetRequestGenerator();
|
return FetchReleases(g => g.GetSearchRequests(searchCriteria));
|
||||||
|
|
||||||
return FetchReleases(generator.GetSearchRequests(searchCriteria));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IList<ReleaseInfo> Fetch(DailyEpisodeSearchCriteria searchCriteria)
|
public override IList<ReleaseInfo> Fetch(DailyEpisodeSearchCriteria searchCriteria)
|
||||||
|
@ -82,9 +76,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
return new List<ReleaseInfo>();
|
return new List<ReleaseInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var generator = GetRequestGenerator();
|
return FetchReleases(g => g.GetSearchRequests(searchCriteria));
|
||||||
|
|
||||||
return FetchReleases(generator.GetSearchRequests(searchCriteria));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IList<ReleaseInfo> Fetch(AnimeEpisodeSearchCriteria searchCriteria)
|
public override IList<ReleaseInfo> Fetch(AnimeEpisodeSearchCriteria searchCriteria)
|
||||||
|
@ -94,9 +86,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
return new List<ReleaseInfo>();
|
return new List<ReleaseInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var generator = GetRequestGenerator();
|
return FetchReleases(g => g.GetSearchRequests(searchCriteria));
|
||||||
|
|
||||||
return FetchReleases(generator.GetSearchRequests(searchCriteria));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IList<ReleaseInfo> Fetch(SpecialEpisodeSearchCriteria searchCriteria)
|
public override IList<ReleaseInfo> Fetch(SpecialEpisodeSearchCriteria searchCriteria)
|
||||||
|
@ -106,20 +96,21 @@ namespace NzbDrone.Core.Indexers
|
||||||
return new List<ReleaseInfo>();
|
return new List<ReleaseInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var generator = GetRequestGenerator();
|
return FetchReleases(g => g.GetSearchRequests(searchCriteria));
|
||||||
|
|
||||||
return FetchReleases(generator.GetSearchRequests(searchCriteria));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual IList<ReleaseInfo> FetchReleases(IndexerPageableRequestChain pageableRequestChain, bool isRecent = false)
|
protected virtual IList<ReleaseInfo> FetchReleases(Func<IIndexerRequestGenerator, IndexerPageableRequestChain> pageableRequestChainSelector, bool isRecent = false)
|
||||||
{
|
{
|
||||||
var releases = new List<ReleaseInfo>();
|
var releases = new List<ReleaseInfo>();
|
||||||
var url = string.Empty;
|
var url = string.Empty;
|
||||||
|
|
||||||
var parser = GetParser();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var generator = GetRequestGenerator();
|
||||||
|
var parser = GetParser();
|
||||||
|
|
||||||
|
var pageableRequestChain = pageableRequestChainSelector(generator);
|
||||||
|
|
||||||
var fullyUpdated = false;
|
var fullyUpdated = false;
|
||||||
ReleaseInfo lastReleaseInfo = null;
|
ReleaseInfo lastReleaseInfo = null;
|
||||||
if (isRecent)
|
if (isRecent)
|
||||||
|
@ -222,18 +213,22 @@ namespace NzbDrone.Core.Indexers
|
||||||
_logger.Warn("{0} {1} {2}", this, url, webException.Message);
|
_logger.Warn("{0} {1} {2}", this, url, webException.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (HttpException httpException)
|
catch (TooManyRequestsException ex)
|
||||||
{
|
{
|
||||||
if ((int)httpException.Response.StatusCode == 429)
|
if (ex.RetryAfter != TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
_indexerStatusService.RecordFailure(Definition.Id, TimeSpan.FromHours(1));
|
_indexerStatusService.RecordFailure(Definition.Id, ex.RetryAfter);
|
||||||
_logger.Warn("API Request Limit reached for {0}", this);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_indexerStatusService.RecordFailure(Definition.Id);
|
_indexerStatusService.RecordFailure(Definition.Id, TimeSpan.FromHours(1));
|
||||||
_logger.Warn("{0} {1}", this, httpException.Message);
|
|
||||||
}
|
}
|
||||||
|
_logger.Warn("API Request Limit reached for {0}", this);
|
||||||
|
}
|
||||||
|
catch (HttpException ex)
|
||||||
|
{
|
||||||
|
_indexerStatusService.RecordFailure(Definition.Id);
|
||||||
|
_logger.Warn("{0} {1}", this, ex.Message);
|
||||||
}
|
}
|
||||||
catch (RequestLimitReachedException)
|
catch (RequestLimitReachedException)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue