mirror of
https://github.com/lidarr/Lidarr
synced 2024-12-26 01:27:00 +00:00
Fixed: A season pack import taking a long time should no longer cause the download to be deleted prematurely.
This commit is contained in:
parent
95bd82778f
commit
d0bf539a73
3 changed files with 126 additions and 18 deletions
|
@ -40,7 +40,7 @@ public void should_hold_the_call_for_debounce_duration()
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void should_throttle_cals()
|
||||
public void should_throttle_calls()
|
||||
{
|
||||
var counter = new Counter();
|
||||
var debounceFunction = new Debouncer(counter.Hit, TimeSpan.FromMilliseconds(50));
|
||||
|
@ -64,6 +64,62 @@ public void should_throttle_cals()
|
|||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_hold_the_call_while_paused()
|
||||
{
|
||||
var counter = new Counter();
|
||||
var debounceFunction = new Debouncer(counter.Hit, TimeSpan.FromMilliseconds(50));
|
||||
|
||||
debounceFunction.Pause();
|
||||
|
||||
debounceFunction.Execute();
|
||||
debounceFunction.Execute();
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
||||
counter.Count.Should().Be(0);
|
||||
|
||||
debounceFunction.Execute();
|
||||
debounceFunction.Execute();
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
||||
counter.Count.Should().Be(0);
|
||||
|
||||
debounceFunction.Resume();
|
||||
|
||||
Thread.Sleep(20);
|
||||
|
||||
counter.Count.Should().Be(0);
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
||||
counter.Count.Should().Be(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_handle_pause_reentrancy()
|
||||
{
|
||||
var counter = new Counter();
|
||||
var debounceFunction = new Debouncer(counter.Hit, TimeSpan.FromMilliseconds(50));
|
||||
|
||||
debounceFunction.Pause();
|
||||
debounceFunction.Pause();
|
||||
|
||||
debounceFunction.Execute();
|
||||
debounceFunction.Execute();
|
||||
|
||||
debounceFunction.Resume();
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
||||
counter.Count.Should().Be(0);
|
||||
|
||||
debounceFunction.Resume();
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
||||
counter.Count.Should().Be(1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace NzbDrone.Common.TPL
|
||||
{
|
||||
|
@ -7,6 +8,9 @@ public class Debouncer
|
|||
private readonly Action _action;
|
||||
private readonly System.Timers.Timer _timer;
|
||||
|
||||
private volatile int _paused;
|
||||
private volatile bool _triggered;
|
||||
|
||||
public Debouncer(Action action, TimeSpan debounceDuration)
|
||||
{
|
||||
_action = action;
|
||||
|
@ -16,13 +20,45 @@ public Debouncer(Action action, TimeSpan debounceDuration)
|
|||
|
||||
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
_timer.Stop();
|
||||
_action();
|
||||
if (_paused == 0)
|
||||
{
|
||||
_triggered = false;
|
||||
_timer.Stop();
|
||||
_action();
|
||||
}
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
_timer.Start();
|
||||
lock (_timer)
|
||||
{
|
||||
_triggered = true;
|
||||
if (_paused == 0)
|
||||
{
|
||||
_timer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
lock (_timer)
|
||||
{
|
||||
_paused++;
|
||||
_timer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void Resume()
|
||||
{
|
||||
lock (_timer)
|
||||
{
|
||||
_paused--;
|
||||
if (_paused == 0 && _triggered)
|
||||
{
|
||||
_timer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,11 +12,12 @@
|
|||
namespace NzbDrone.Core.Download.TrackedDownloads
|
||||
{
|
||||
public class DownloadMonitoringService : IExecute<CheckForFinishedDownloadCommand>,
|
||||
IHandleAsync<EpisodeGrabbedEvent>,
|
||||
IHandleAsync<EpisodeImportedEvent>
|
||||
IHandle<EpisodeGrabbedEvent>,
|
||||
IHandle<EpisodeImportedEvent>
|
||||
{
|
||||
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IManageCommandQueue _manageCommandQueue;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IFailedDownloadService _failedDownloadService;
|
||||
private readonly ICompletedDownloadService _completedDownloadService;
|
||||
|
@ -26,6 +27,7 @@ public class DownloadMonitoringService : IExecute<CheckForFinishedDownloadComman
|
|||
|
||||
public DownloadMonitoringService(IProvideDownloadClient downloadClientProvider,
|
||||
IEventAggregator eventAggregator,
|
||||
IManageCommandQueue manageCommandQueue,
|
||||
IConfigService configService,
|
||||
IFailedDownloadService failedDownloadService,
|
||||
ICompletedDownloadService completedDownloadService,
|
||||
|
@ -34,28 +36,42 @@ public DownloadMonitoringService(IProvideDownloadClient downloadClientProvider,
|
|||
{
|
||||
_downloadClientProvider = downloadClientProvider;
|
||||
_eventAggregator = eventAggregator;
|
||||
_manageCommandQueue = manageCommandQueue;
|
||||
_configService = configService;
|
||||
_failedDownloadService = failedDownloadService;
|
||||
_completedDownloadService = completedDownloadService;
|
||||
_trackedDownloadService = trackedDownloadService;
|
||||
_logger = logger;
|
||||
|
||||
_refreshDebounce = new Debouncer(Refresh, TimeSpan.FromSeconds(5));
|
||||
_refreshDebounce = new Debouncer(QueueRefresh, TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
private void QueueRefresh()
|
||||
{
|
||||
_manageCommandQueue.Push(new CheckForFinishedDownloadCommand());
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
var downloadClients = _downloadClientProvider.GetDownloadClients();
|
||||
|
||||
var trackedDownload = new List<TrackedDownload>();
|
||||
|
||||
foreach (var downloadClient in downloadClients)
|
||||
_refreshDebounce.Pause();
|
||||
try
|
||||
{
|
||||
var clientTrackedDownloads = ProcessClientDownloads(downloadClient);
|
||||
trackedDownload.AddRange(clientTrackedDownloads.Where(c => c.State == TrackedDownloadStage.Downloading));
|
||||
}
|
||||
var downloadClients = _downloadClientProvider.GetDownloadClients();
|
||||
|
||||
_eventAggregator.PublishEvent(new TrackedDownloadRefreshedEvent(trackedDownload));
|
||||
var trackedDownload = new List<TrackedDownload>();
|
||||
|
||||
foreach (var downloadClient in downloadClients)
|
||||
{
|
||||
var clientTrackedDownloads = ProcessClientDownloads(downloadClient);
|
||||
trackedDownload.AddRange(clientTrackedDownloads.Where(c => c.State == TrackedDownloadStage.Downloading));
|
||||
}
|
||||
|
||||
_eventAggregator.PublishEvent(new TrackedDownloadRefreshedEvent(trackedDownload));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_refreshDebounce.Resume();
|
||||
}
|
||||
}
|
||||
|
||||
private List<TrackedDownload> ProcessClientDownloads(IDownloadClient downloadClient)
|
||||
|
@ -128,12 +144,12 @@ public void Execute(CheckForFinishedDownloadCommand message)
|
|||
Refresh();
|
||||
}
|
||||
|
||||
public void HandleAsync(EpisodeGrabbedEvent message)
|
||||
public void Handle(EpisodeGrabbedEvent message)
|
||||
{
|
||||
_refreshDebounce.Execute();
|
||||
}
|
||||
|
||||
public void HandleAsync(EpisodeImportedEvent message)
|
||||
public void Handle(EpisodeImportedEvent message)
|
||||
{
|
||||
_refreshDebounce.Execute();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue