From f8afe65f7ef0a06e594d97166bf51f00343d58d9 Mon Sep 17 00:00:00 2001 From: Qstick Date: Sun, 26 Jul 2020 21:23:10 +0100 Subject: [PATCH] Fixed: Performance issue when scanning large root folder --- src/NzbDrone.Common/Disk/DiskProviderBase.cs | 7 ++++ src/NzbDrone.Common/Disk/IDiskProvider.cs | 1 + .../DiskScanServiceTests/ScanFixture.cs | 3 +- .../MediaFiles/DiskScanService.cs | 33 ++++++++++--------- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/NzbDrone.Common/Disk/DiskProviderBase.cs b/src/NzbDrone.Common/Disk/DiskProviderBase.cs index bda56eb3e..9517b8ccf 100644 --- a/src/NzbDrone.Common/Disk/DiskProviderBase.cs +++ b/src/NzbDrone.Common/Disk/DiskProviderBase.cs @@ -149,6 +149,13 @@ namespace NzbDrone.Common.Disk } } + public bool FolderEmpty(string path) + { + Ensure.That(path, () => path).IsValidPath(); + + return _fileSystem.Directory.EnumerateFileSystemEntries(path).Empty(); + } + public string[] GetDirectories(string path) { Ensure.That(path, () => path).IsValidPath(); diff --git a/src/NzbDrone.Common/Disk/IDiskProvider.cs b/src/NzbDrone.Common/Disk/IDiskProvider.cs index e3bbc23f7..2fe2f6359 100644 --- a/src/NzbDrone.Common/Disk/IDiskProvider.cs +++ b/src/NzbDrone.Common/Disk/IDiskProvider.cs @@ -22,6 +22,7 @@ namespace NzbDrone.Common.Disk bool FileExists(string path); bool FileExists(string path, StringComparison stringComparison); bool FolderWritable(string path); + bool FolderEmpty(string path); string[] GetDirectories(string path); string[] GetFiles(string path, SearchOption searchOption); long GetFolderSize(string path); diff --git a/src/NzbDrone.Core.Test/MediaFiles/DiskScanServiceTests/ScanFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/DiskScanServiceTests/ScanFixture.cs index 70fecacbc..23b6076ae 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/DiskScanServiceTests/ScanFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/DiskScanServiceTests/ScanFixture.cs @@ -9,6 +9,7 @@ using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Common.Disk; +using NzbDrone.Common.Extensions; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.TrackImport; @@ -139,7 +140,7 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests ExceptionVerification.ExpectedWarns(1); Mocker.GetMock() - .Verify(v => v.FolderExists(_artist.Path), Times.Never()); + .Verify(v => v.GetFiles(_artist.Path, SearchOption.AllDirectories), Times.Never()); Mocker.GetMock() .Verify(v => v.Clean(It.IsAny(), It.IsAny>()), Times.Never()); diff --git a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs index 62f1f1664..b6e2fe5f3 100644 --- a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs +++ b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs @@ -95,25 +95,28 @@ namespace NzbDrone.Core.MediaFiles return; } - if (!_diskProvider.FolderExists(rootFolder.Path)) - { - _logger.Warn("Root folder {0} doesn't exist.", rootFolder.Path); - - var skippedArtists = _artistService.GetArtists(artistIds); - skippedArtists.ForEach(x => _eventAggregator.PublishEvent(new ArtistScanSkippedEvent(x, ArtistScanSkippedReason.RootFolderDoesNotExist))); - return; - } + var folderExists = _diskProvider.FolderExists(folder); - if (_diskProvider.GetDirectories(rootFolder.Path).Empty()) + if (!folderExists) { - _logger.Warn("Root folder {0} is empty.", rootFolder.Path); - - var skippedArtists = _artistService.GetArtists(artistIds); - skippedArtists.ForEach(x => _eventAggregator.PublishEvent(new ArtistScanSkippedEvent(x, ArtistScanSkippedReason.RootFolderIsEmpty))); - return; + if (!_diskProvider.FolderExists(rootFolder.Path)) + { + _logger.Warn("Artists' root folder ({0}) doesn't exist.", rootFolder); + var skippedArtists = _artistService.GetArtists(artistIds); + skippedArtists.ForEach(x => _eventAggregator.PublishEvent(new ArtistScanSkippedEvent(x, ArtistScanSkippedReason.RootFolderDoesNotExist))); + return; + } + + if (_diskProvider.FolderEmpty(rootFolder.Path)) + { + _logger.Warn("Artists' root folder ({0}) is empty.", rootFolder); + var skippedArtists = _artistService.GetArtists(artistIds); + skippedArtists.ForEach(x => _eventAggregator.PublishEvent(new ArtistScanSkippedEvent(x, ArtistScanSkippedReason.RootFolderIsEmpty))); + return; + } } - if (!_diskProvider.FolderExists(folder)) + if (!folderExists) { _logger.Debug("Specified scan folder ({0}) doesn't exist.", folder);