diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientStatusServiceFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientStatusServiceFixture.cs index 0ddae11a2..08aca1cdb 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientStatusServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientStatusServiceFixture.cs @@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.Download _epoch = DateTime.UtcNow; } - private void WithStatus(DownloadClientStatus status) + private DownloadClientStatus WithStatus(DownloadClientStatus status) { Mocker.GetMock() .Setup(v => v.FindByProviderId(1)) @@ -27,6 +27,8 @@ namespace NzbDrone.Core.Test.Download Mocker.GetMock() .Setup(v => v.All()) .Returns(new[] { status }); + + return status; } private void VerifyUpdate() @@ -77,6 +79,54 @@ namespace NzbDrone.Core.Test.Download status.Should().NotBeNull(); } + [Test] + public void should_not_escalate_further_till_after_5_minutes_since_initial_failure() + { + var origStatus = WithStatus(new DownloadClientStatus + { + InitialFailure = _epoch - TimeSpan.FromMinutes(4), + MostRecentFailure = _epoch - TimeSpan.FromSeconds(4), + EscalationLevel = 3 + }); + + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + + var status = Subject.GetBlockedProviders().FirstOrDefault(); + status.Should().BeNull(); + + origStatus.EscalationLevel.Should().Be(3); + } + + [Test] + public void should_escalate_further_after_5_minutes_since_initial_failure() + { + WithStatus(new DownloadClientStatus + { + InitialFailure = _epoch - TimeSpan.FromMinutes(6), + MostRecentFailure = _epoch - TimeSpan.FromSeconds(120), + EscalationLevel = 3 + }); + + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + Subject.RecordFailure(1); + + var status = Subject.GetBlockedProviders().FirstOrDefault(); + status.Should().NotBeNull(); + + status.EscalationLevel.Should().BeGreaterThan(3); + } + [Test] public void should_not_escalate_beyond_3_hours() { diff --git a/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs b/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs index 8ea34d47e..7c5710e7b 100644 --- a/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs +++ b/src/NzbDrone.Core/ThingiProvider/Status/ProviderStatusServiceBase.cs @@ -93,14 +93,18 @@ namespace NzbDrone.Core.ThingiProvider.Status var status = GetProviderStatus(providerId); var now = DateTime.UtcNow; + status.MostRecentFailure = now; if (status.EscalationLevel == 0) { status.InitialFailure = now; + status.EscalationLevel = 1; + escalate = false; } - status.MostRecentFailure = now; - if (escalate) + var inGracePeriod = (status.InitialFailure.Value + MinimumTimeSinceInitialFailure) > now; + + if (escalate && !inGracePeriod) { status.EscalationLevel = Math.Min(MaximumEscalationLevel, status.EscalationLevel + 1); } @@ -113,7 +117,7 @@ namespace NzbDrone.Core.ThingiProvider.Status } } - if (status.InitialFailure.Value + MinimumTimeSinceInitialFailure <= now || minimumBackOff != TimeSpan.Zero) + if (!inGracePeriod || minimumBackOff != TimeSpan.Zero) { status.DisabledTill = now + CalculateBackOffPeriod(status); }