Fixed: Performance issue when scanning large root folder

This commit is contained in:
Taloth Saldono 2020-05-13 21:27:39 +02:00
parent 4f7e00bdc4
commit d3a22459ac
4 changed files with 37 additions and 13 deletions

View File

@ -141,6 +141,13 @@ namespace NzbDrone.Common.Disk
} }
} }
public bool FolderEmpty(string path)
{
Ensure.That(path, () => path).IsValidPath();
return Directory.EnumerateDirectories(path).Empty();
}
public string[] GetDirectories(string path) public string[] GetDirectories(string path)
{ {
Ensure.That(path, () => path).IsValidPath(); Ensure.That(path, () => path).IsValidPath();

View File

@ -21,6 +21,7 @@ namespace NzbDrone.Common.Disk
bool FileExists(string path); bool FileExists(string path);
bool FileExists(string path, StringComparison stringComparison); bool FileExists(string path, StringComparison stringComparison);
bool FolderWritable(string path); bool FolderWritable(string path);
bool FolderEmpty(string path);
string[] GetDirectories(string path); string[] GetDirectories(string path);
string[] GetFiles(string path, SearchOption searchOption); string[] GetFiles(string path, SearchOption searchOption);
long GetFolderSize(string path); long GetFolderSize(string path);

View File

@ -5,6 +5,7 @@ using FizzWare.NBuilder;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.EpisodeImport; using NzbDrone.Core.MediaFiles.EpisodeImport;
@ -56,6 +57,10 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
.Setup(s => s.GetDirectories(_rootFolder)) .Setup(s => s.GetDirectories(_rootFolder))
.Returns(subfolders); .Returns(subfolders);
Mocker.GetMock<IDiskProvider>()
.Setup(s => s.FolderEmpty(_rootFolder))
.Returns(subfolders.Empty());
foreach (var folder in subfolders) foreach (var folder in subfolders)
{ {
Mocker.GetMock<IDiskProvider>() Mocker.GetMock<IDiskProvider>()
@ -84,7 +89,10 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
ExceptionVerification.ExpectedWarns(1); ExceptionVerification.ExpectedWarns(1);
Mocker.GetMock<IDiskProvider>() Mocker.GetMock<IDiskProvider>()
.Verify(v => v.FolderExists(_series.Path), Times.Never()); .Verify(v => v.GetFiles(_series.Path, SearchOption.AllDirectories), Times.Never());
Mocker.GetMock<IDiskProvider>()
.Verify(v => v.CreateFolder(_series.Path), Times.Never());
Mocker.GetMock<IMediaFileTableCleanupService>() Mocker.GetMock<IMediaFileTableCleanupService>()
.Verify(v => v.Clean(It.IsAny<Series>(), It.IsAny<List<string>>()), Times.Never()); .Verify(v => v.Clean(It.IsAny<Series>(), It.IsAny<List<string>>()), Times.Never());
@ -100,7 +108,10 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
ExceptionVerification.ExpectedWarns(1); ExceptionVerification.ExpectedWarns(1);
Mocker.GetMock<IDiskProvider>() Mocker.GetMock<IDiskProvider>()
.Verify(v => v.FolderExists(_series.Path), Times.Never()); .Verify(v => v.GetFiles(_series.Path, SearchOption.AllDirectories), Times.Never());
Mocker.GetMock<IDiskProvider>()
.Verify(v => v.CreateFolder(_series.Path), Times.Never());
Mocker.GetMock<IMediaFileTableCleanupService>() Mocker.GetMock<IMediaFileTableCleanupService>()
.Verify(v => v.Clean(It.IsAny<Series>(), It.IsAny<List<string>>()), Times.Never()); .Verify(v => v.Clean(It.IsAny<Series>(), It.IsAny<List<string>>()), Times.Never());

View File

@ -69,23 +69,28 @@ namespace NzbDrone.Core.MediaFiles
{ {
var rootFolder = _rootFolderService.GetBestRootFolderPath(series.Path); var rootFolder = _rootFolderService.GetBestRootFolderPath(series.Path);
if (!_diskProvider.FolderExists(rootFolder)) var seriesFolderExists = _diskProvider.FolderExists(series.Path);
{
_logger.Warn("Series' root folder ({0}) doesn't exist.", rootFolder);
_eventAggregator.PublishEvent(new SeriesScanSkippedEvent(series, SeriesScanSkippedReason.RootFolderDoesNotExist));
return;
}
if (_diskProvider.GetDirectories(rootFolder).Empty()) if (!seriesFolderExists)
{ {
_logger.Warn("Series' root folder ({0}) is empty.", rootFolder); if (!_diskProvider.FolderExists(rootFolder))
_eventAggregator.PublishEvent(new SeriesScanSkippedEvent(series, SeriesScanSkippedReason.RootFolderIsEmpty)); {
return; _logger.Warn("Series' root folder ({0}) doesn't exist.", rootFolder);
_eventAggregator.PublishEvent(new SeriesScanSkippedEvent(series, SeriesScanSkippedReason.RootFolderDoesNotExist));
return;
}
if (_diskProvider.FolderEmpty(rootFolder))
{
_logger.Warn("Series' root folder ({0}) is empty.", rootFolder);
_eventAggregator.PublishEvent(new SeriesScanSkippedEvent(series, SeriesScanSkippedReason.RootFolderIsEmpty));
return;
}
} }
_logger.ProgressInfo("Scanning {0}", series.Title); _logger.ProgressInfo("Scanning {0}", series.Title);
if (!_diskProvider.FolderExists(series.Path)) if (!seriesFolderExists)
{ {
if (_configService.CreateEmptySeriesFolders) if (_configService.CreateEmptySeriesFolders)
{ {