Fixed: Don't refresh and rescan artist when new album added

Speeds up adding a single album to an existing artist.  Should help
reduce the number of full rescans being triggered also - an added
album was triggering one.
This commit is contained in:
ta264 2020-08-25 21:16:44 +01:00 committed by Qstick
commit 12d6b5ee9a
9 changed files with 60 additions and 20 deletions

View file

@ -54,8 +54,8 @@ namespace NzbDrone.Core.Test.ImportListTests
.Returns((List<Artist> artists, bool doRefresh) => artists); .Returns((List<Artist> artists, bool doRefresh) => artists);
Mocker.GetMock<IAddAlbumService>() Mocker.GetMock<IAddAlbumService>()
.Setup(v => v.AddAlbums(It.IsAny<List<Album>>())) .Setup(v => v.AddAlbums(It.IsAny<List<Album>>(), false))
.Returns((List<Album> albums) => albums); .Returns((List<Album> albums, bool doRefresh) => albums);
} }
private void WithAlbum() private void WithAlbum()
@ -208,7 +208,7 @@ namespace NzbDrone.Core.Test.ImportListTests
Subject.Execute(new ImportListSyncCommand()); Subject.Execute(new ImportListSyncCommand());
Mocker.GetMock<IAddAlbumService>() Mocker.GetMock<IAddAlbumService>()
.Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 1))); .Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 1), false));
} }
[TestCase(ImportListMonitorType.None, false)] [TestCase(ImportListMonitorType.None, false)]
@ -236,7 +236,7 @@ namespace NzbDrone.Core.Test.ImportListTests
Subject.Execute(new ImportListSyncCommand()); Subject.Execute(new ImportListSyncCommand());
Mocker.GetMock<IAddAlbumService>() Mocker.GetMock<IAddAlbumService>()
.Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 1 && t.First().Monitored == expectedAlbumMonitored))); .Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 1 && t.First().Monitored == expectedAlbumMonitored), false));
} }
[Test] [Test]
@ -260,7 +260,7 @@ namespace NzbDrone.Core.Test.ImportListTests
Subject.Execute(new ImportListSyncCommand()); Subject.Execute(new ImportListSyncCommand());
Mocker.GetMock<IAddAlbumService>() Mocker.GetMock<IAddAlbumService>()
.Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 0))); .Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 0), false));
} }
[Test] [Test]
@ -273,7 +273,7 @@ namespace NzbDrone.Core.Test.ImportListTests
Subject.Execute(new ImportListSyncCommand()); Subject.Execute(new ImportListSyncCommand());
Mocker.GetMock<IAddAlbumService>() Mocker.GetMock<IAddAlbumService>()
.Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 0))); .Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 0), false));
} }
} }
} }

View file

@ -118,7 +118,7 @@ namespace NzbDrone.Core.ImportLists
} }
var addedArtists = _addArtistService.AddArtists(artistsToAdd, false); var addedArtists = _addArtistService.AddArtists(artistsToAdd, false);
var addedAlbums = _addAlbumService.AddAlbums(albumsToAdd); var addedAlbums = _addAlbumService.AddAlbums(albumsToAdd, false);
var message = string.Format($"Import List Sync Completed. Items found: {reports.Count}, Artists added: {addedArtists.Count}, Albums added: {addedAlbums.Count}"); var message = string.Format($"Import List Sync Completed. Items found: {reports.Count}, Artists added: {addedArtists.Count}, Albums added: {addedAlbums.Count}");

View file

@ -26,6 +26,7 @@ namespace NzbDrone.Core.MediaCover
public class MediaCoverService : public class MediaCoverService :
IHandleAsync<ArtistRefreshCompleteEvent>, IHandleAsync<ArtistRefreshCompleteEvent>,
IHandleAsync<ArtistDeletedEvent>, IHandleAsync<ArtistDeletedEvent>,
IHandleAsync<AlbumAddedEvent>,
IHandleAsync<AlbumDeletedEvent>, IHandleAsync<AlbumDeletedEvent>,
IMapCoversToLocal IMapCoversToLocal
{ {
@ -292,6 +293,14 @@ namespace NzbDrone.Core.MediaCover
} }
} }
public void HandleAsync(AlbumAddedEvent message)
{
if (message.DoRefresh)
{
EnsureAlbumCovers(message.Album);
}
}
public void HandleAsync(AlbumDeletedEvent message) public void HandleAsync(AlbumDeletedEvent message)
{ {
var path = GetAlbumCoverPath(message.Album.Id); var path = GetAlbumCoverPath(message.Album.Id);

View file

@ -5,14 +5,16 @@ namespace NzbDrone.Core.Music.Commands
public class RefreshAlbumCommand : Command public class RefreshAlbumCommand : Command
{ {
public int? AlbumId { get; set; } public int? AlbumId { get; set; }
public bool IsNewAlbum { get; set; }
public RefreshAlbumCommand() public RefreshAlbumCommand()
{ {
} }
public RefreshAlbumCommand(int? albumId) public RefreshAlbumCommand(int? albumId, bool isNewAlbum = false)
{ {
AlbumId = albumId; AlbumId = albumId;
IsNewAlbum = isNewAlbum;
} }
public override bool SendUpdatesToClient => true; public override bool SendUpdatesToClient => true;

View file

@ -5,10 +5,12 @@ namespace NzbDrone.Core.Music.Events
public class AlbumAddedEvent : IEvent public class AlbumAddedEvent : IEvent
{ {
public Album Album { get; private set; } public Album Album { get; private set; }
public bool DoRefresh { get; private set; }
public AlbumAddedEvent(Album album) public AlbumAddedEvent(Album album, bool doRefresh = true)
{ {
Album = album; Album = album;
DoRefresh = doRefresh;
} }
} }
} }

View file

@ -7,16 +7,31 @@ namespace NzbDrone.Core.Music
{ {
public class AlbumAddedHandler : IHandle<AlbumAddedEvent> public class AlbumAddedHandler : IHandle<AlbumAddedEvent>
{ {
private readonly ICheckIfArtistShouldBeRefreshed _checkIfArtistShouldBeRefreshed;
private readonly IManageCommandQueue _commandQueueManager; private readonly IManageCommandQueue _commandQueueManager;
public AlbumAddedHandler(IManageCommandQueue commandQueueManager) public AlbumAddedHandler(ICheckIfArtistShouldBeRefreshed checkIfArtistShouldBeRefreshed,
IManageCommandQueue commandQueueManager)
{ {
_checkIfArtistShouldBeRefreshed = checkIfArtistShouldBeRefreshed;
_commandQueueManager = commandQueueManager; _commandQueueManager = commandQueueManager;
} }
public void Handle(AlbumAddedEvent message) public void Handle(AlbumAddedEvent message)
{ {
_commandQueueManager.Push(new RefreshArtistCommand(message.Album.Artist.Value.Id)); if (message.DoRefresh)
{
var artist = message.Album.Artist.Value;
if (_checkIfArtistShouldBeRefreshed.ShouldRefresh(artist))
{
_commandQueueManager.Push(new RefreshArtistCommand(artist.Id));
}
else
{
_commandQueueManager.Push(new RefreshAlbumCommand(message.Album.Id, true));
}
}
} }
} }
} }

View file

@ -12,8 +12,8 @@ namespace NzbDrone.Core.Music
{ {
public interface IAddAlbumService public interface IAddAlbumService
{ {
Album AddAlbum(Album album); Album AddAlbum(Album album, bool doRefresh = true);
List<Album> AddAlbums(List<Album> albums); List<Album> AddAlbums(List<Album> albums, bool doRefresh = true);
} }
public class AddAlbumService : IAddAlbumService public class AddAlbumService : IAddAlbumService
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Music
_logger = logger; _logger = logger;
} }
public Album AddAlbum(Album album) public Album AddAlbum(Album album, bool doRefresh = true)
{ {
_logger.Debug($"Adding album {album}"); _logger.Debug($"Adding album {album}");
@ -65,12 +65,13 @@ namespace NzbDrone.Core.Music
} }
album.ArtistMetadataId = dbArtist.ArtistMetadataId; album.ArtistMetadataId = dbArtist.ArtistMetadataId;
_albumService.AddAlbum(album); album.Artist = dbArtist;
_albumService.AddAlbum(album, doRefresh);
return album; return album;
} }
public List<Album> AddAlbums(List<Album> albums) public List<Album> AddAlbums(List<Album> albums, bool doRefresh = true)
{ {
var added = DateTime.UtcNow; var added = DateTime.UtcNow;
var addedAlbums = new List<Album>(); var addedAlbums = new List<Album>();
@ -78,7 +79,7 @@ namespace NzbDrone.Core.Music
foreach (var a in albums) foreach (var a in albums)
{ {
a.Added = added; a.Added = added;
addedAlbums.Add(AddAlbum(a)); addedAlbums.Add(AddAlbum(a, doRefresh));
} }
return addedAlbums; return addedAlbums;

View file

@ -19,7 +19,7 @@ namespace NzbDrone.Core.Music
List<Album> GetLastAlbumsByArtistMetadataId(IEnumerable<int> artistMetadataIds); List<Album> GetLastAlbumsByArtistMetadataId(IEnumerable<int> artistMetadataIds);
List<Album> GetAlbumsByArtistMetadataId(int artistMetadataId); List<Album> GetAlbumsByArtistMetadataId(int artistMetadataId);
List<Album> GetAlbumsForRefresh(int artistMetadataId, IEnumerable<string> foreignIds); List<Album> GetAlbumsForRefresh(int artistMetadataId, IEnumerable<string> foreignIds);
Album AddAlbum(Album newAlbum); Album AddAlbum(Album newAlbum, bool doRefresh);
Album FindById(string foreignId); Album FindById(string foreignId);
Album FindByTitle(int artistMetadataId, string title); Album FindByTitle(int artistMetadataId, string title);
Album FindByTitleInexact(int artistMetadataId, string title); Album FindByTitleInexact(int artistMetadataId, string title);
@ -57,11 +57,11 @@ namespace NzbDrone.Core.Music
_logger = logger; _logger = logger;
} }
public Album AddAlbum(Album newAlbum) public Album AddAlbum(Album newAlbum, bool doRefresh)
{ {
_albumRepository.Insert(newAlbum); _albumRepository.Insert(newAlbum);
_eventAggregator.PublishEvent(new AlbumAddedEvent(GetAlbum(newAlbum.Id))); _eventAggregator.PublishEvent(new AlbumAddedEvent(GetAlbum(newAlbum.Id), doRefresh));
return newAlbum; return newAlbum;
} }

View file

@ -8,6 +8,7 @@ using NzbDrone.Core.Exceptions;
using NzbDrone.Core.History; using NzbDrone.Core.History;
using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Commands;
using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.MetadataSource; using NzbDrone.Core.MetadataSource;
@ -33,6 +34,7 @@ namespace NzbDrone.Core.Music
private readonly IMediaFileService _mediaFileService; private readonly IMediaFileService _mediaFileService;
private readonly IHistoryService _historyService; private readonly IHistoryService _historyService;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IManageCommandQueue _commandQueueManager;
private readonly ICheckIfAlbumShouldBeRefreshed _checkIfAlbumShouldBeRefreshed; private readonly ICheckIfAlbumShouldBeRefreshed _checkIfAlbumShouldBeRefreshed;
private readonly IMapCoversToLocal _mediaCoverService; private readonly IMapCoversToLocal _mediaCoverService;
private readonly Logger _logger; private readonly Logger _logger;
@ -47,6 +49,7 @@ namespace NzbDrone.Core.Music
IMediaFileService mediaFileService, IMediaFileService mediaFileService,
IHistoryService historyService, IHistoryService historyService,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
IManageCommandQueue commandQueueManager,
ICheckIfAlbumShouldBeRefreshed checkIfAlbumShouldBeRefreshed, ICheckIfAlbumShouldBeRefreshed checkIfAlbumShouldBeRefreshed,
IMapCoversToLocal mediaCoverService, IMapCoversToLocal mediaCoverService,
Logger logger) Logger logger)
@ -61,6 +64,7 @@ namespace NzbDrone.Core.Music
_mediaFileService = mediaFileService; _mediaFileService = mediaFileService;
_historyService = historyService; _historyService = historyService;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_commandQueueManager = commandQueueManager;
_checkIfAlbumShouldBeRefreshed = checkIfAlbumShouldBeRefreshed; _checkIfAlbumShouldBeRefreshed = checkIfAlbumShouldBeRefreshed;
_mediaCoverService = mediaCoverService; _mediaCoverService = mediaCoverService;
_logger = logger; _logger = logger;
@ -359,6 +363,13 @@ namespace NzbDrone.Core.Music
_eventAggregator.PublishEvent(new ArtistUpdatedEvent(artist)); _eventAggregator.PublishEvent(new ArtistUpdatedEvent(artist));
_eventAggregator.PublishEvent(new AlbumUpdatedEvent(album)); _eventAggregator.PublishEvent(new AlbumUpdatedEvent(album));
} }
if (message.IsNewAlbum)
{
// Just scan the artist path - triggering a full rescan is too painful
var folders = new List<string> { artist.Path };
_commandQueueManager.Push(new RescanFoldersCommand(folders, FilterFilesType.Matched, false, null));
}
} }
} }
} }