Fixed: Various performance improvements for large collections

pull/3127/head
Taloth Saldono 6 years ago
parent 9e68653949
commit 0dccc7e91e

@ -0,0 +1,51 @@
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Housekeeping.Housekeepers;
using NzbDrone.Core.Profiles.Releases;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
{
[TestFixture]
public class UpdateCleanTitleForSeriesFixture : CoreTest<UpdateCleanTitleForSeries>
{
[Test]
public void should_update_clean_title()
{
var series = Builder<Series>.CreateNew()
.With(s => s.Title = "Full Title")
.With(s => s.CleanTitle = "unclean")
.Build();
Mocker.GetMock<ISeriesRepository>()
.Setup(s => s.All())
.Returns(new[] { series });
Subject.Clean();
Mocker.GetMock<ISeriesRepository>()
.Verify(v => v.Update(It.Is<Series>(s => s.CleanTitle == "fulltitle")), Times.Once());
}
[Test]
public void should_not_update_unchanged_title()
{
var series = Builder<Series>.CreateNew()
.With(s => s.Title = "Full Title")
.With(s => s.CleanTitle = "fulltitle")
.Build();
Mocker.GetMock<ISeriesRepository>()
.Setup(s => s.All())
.Returns(new[] { series });
Subject.Clean();
Mocker.GetMock<ISeriesRepository>()
.Verify(v => v.Update(It.Is<Series>(s => s.CleanTitle == "fulltitle")), Times.Never());
}
}
}

@ -263,6 +263,7 @@
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItemsFixture.cs" /> <Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItemsFixture.cs" />
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedMetadataFilesFixture.cs" /> <Compile Include="Housekeeping\Housekeepers\CleanupOrphanedMetadataFilesFixture.cs" />
<Compile Include="Housekeeping\Housekeepers\CleanupDownloadClientUnavailablePendingReleasesFixture.cs" /> <Compile Include="Housekeeping\Housekeepers\CleanupDownloadClientUnavailablePendingReleasesFixture.cs" />
<Compile Include="Housekeeping\Housekeepers\UpdateCleanTitleForSeriesFixture.cs" />
<Compile Include="Housekeeping\Housekeepers\CleanupUnusedTagsFixture.cs" /> <Compile Include="Housekeeping\Housekeepers\CleanupUnusedTagsFixture.cs" />
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedPendingReleasesFixture.cs" /> <Compile Include="Housekeeping\Housekeepers\CleanupOrphanedPendingReleasesFixture.cs" />
<Compile Include="Housekeeping\Housekeepers\FixFutureDownloadClientStatusTimesFixture.cs" /> <Compile Include="Housekeeping\Housekeepers\FixFutureDownloadClientStatusTimesFixture.cs" />

@ -19,8 +19,12 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
series.ForEach(s => series.ForEach(s =>
{ {
s.CleanTitle = s.CleanTitle.CleanSeriesTitle(); var cleanTitle = s.Title.CleanSeriesTitle();
if (s.CleanTitle != cleanTitle)
{
s.CleanTitle = cleanTitle;
_seriesRepository.Update(s); _seriesRepository.Update(s);
}
}); });
} }
} }

@ -27,7 +27,7 @@ namespace NzbDrone.Core.SeriesStats
mapper.AddParameter("currentDate", DateTime.UtcNow); mapper.AddParameter("currentDate", DateTime.UtcNow);
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine(GetSelectClause()); sb.AppendLine(GetSelectClause(false));
sb.AppendLine(GetEpisodeFilesJoin()); sb.AppendLine(GetEpisodeFilesJoin());
sb.AppendLine(GetGroupByClause()); sb.AppendLine(GetGroupByClause());
var queryText = sb.ToString(); var queryText = sb.ToString();
@ -43,16 +43,15 @@ namespace NzbDrone.Core.SeriesStats
mapper.AddParameter("seriesId", seriesId); mapper.AddParameter("seriesId", seriesId);
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine(GetSelectClause()); sb.AppendLine(GetSelectClause(true));
sb.AppendLine(GetEpisodeFilesJoin()); sb.AppendLine(GetEpisodeFilesJoin());
sb.AppendLine("WHERE Episodes.SeriesId = @seriesId");
sb.AppendLine(GetGroupByClause()); sb.AppendLine(GetGroupByClause());
var queryText = sb.ToString(); var queryText = sb.ToString();
return mapper.Query<SeasonStatistics>(queryText); return mapper.Query<SeasonStatistics>(queryText);
} }
private string GetSelectClause() private string GetSelectClause(bool series)
{ {
return @"SELECT Episodes.*, SUM(EpisodeFiles.Size) as SizeOnDisk FROM return @"SELECT Episodes.*, SUM(EpisodeFiles.Size) as SizeOnDisk FROM
(SELECT (SELECT
@ -64,7 +63,8 @@ namespace NzbDrone.Core.SeriesStats
SUM(CASE WHEN EpisodeFileId > 0 THEN 1 ELSE 0 END) AS EpisodeFileCount, SUM(CASE WHEN EpisodeFileId > 0 THEN 1 ELSE 0 END) AS EpisodeFileCount,
MIN(CASE WHEN AirDateUtc < @currentDate OR EpisodeFileId > 0 OR Monitored = 0 THEN NULL ELSE AirDateUtc END) AS NextAiringString, MIN(CASE WHEN AirDateUtc < @currentDate OR EpisodeFileId > 0 OR Monitored = 0 THEN NULL ELSE AirDateUtc END) AS NextAiringString,
MAX(CASE WHEN AirDateUtc >= @currentDate OR EpisodeFileId = 0 AND Monitored = 0 THEN NULL ELSE AirDateUtc END) AS PreviousAiringString MAX(CASE WHEN AirDateUtc >= @currentDate OR EpisodeFileId = 0 AND Monitored = 0 THEN NULL ELSE AirDateUtc END) AS PreviousAiringString
FROM Episodes FROM Episodes" +
(series ? " WHERE Episodes.SeriesId = @seriesId" : "") + @"
GROUP BY Episodes.SeriesId, Episodes.SeasonNumber) as Episodes"; GROUP BY Episodes.SeriesId, Episodes.SeasonNumber) as Episodes";
} }

@ -12,6 +12,7 @@ namespace NzbDrone.SignalR
{ {
public interface IBroadcastSignalRMessage public interface IBroadcastSignalRMessage
{ {
bool IsConnected { get; }
void BroadcastMessage(SignalRMessage message); void BroadcastMessage(SignalRMessage message);
} }
@ -21,6 +22,7 @@ namespace NzbDrone.SignalR
private static string API_KEY; private static string API_KEY;
private readonly Dictionary<string, string> _messageHistory; private readonly Dictionary<string, string> _messageHistory;
private HashSet<string> _connections = new HashSet<string>();
public NzbDronePersistentConnection(IConfigFileProvider configFileProvider) public NzbDronePersistentConnection(IConfigFileProvider configFileProvider)
{ {
@ -28,6 +30,17 @@ namespace NzbDrone.SignalR
_messageHistory = new Dictionary<string, string>(); _messageHistory = new Dictionary<string, string>();
} }
public bool IsConnected
{
get
{
lock (_connections)
{
return _connections.Count != 0;
}
}
}
public void BroadcastMessage(SignalRMessage message) public void BroadcastMessage(SignalRMessage message)
{ {
@ -59,14 +72,34 @@ namespace NzbDrone.SignalR
protected override Task OnConnected(IRequest request, string connectionId) protected override Task OnConnected(IRequest request, string connectionId)
{ {
lock (_connections)
{
_connections.Add(connectionId);
}
return SendVersion(connectionId); return SendVersion(connectionId);
} }
protected override Task OnReconnected(IRequest request, string connectionId) protected override Task OnReconnected(IRequest request, string connectionId)
{ {
lock (_connections)
{
_connections.Add(connectionId);
}
return SendVersion(connectionId); return SendVersion(connectionId);
} }
protected override Task OnDisconnected(IRequest request, string connectionId, bool stopCalled)
{
lock (_connections)
{
_connections.Remove(connectionId);
}
return base.OnDisconnected(request, connectionId, stopCalled);
}
private Task SendVersion(string connectionId) private Task SendVersion(string connectionId)
{ {
return Context.Connection.Send(connectionId, new SignalRMessage return Context.Connection.Send(connectionId, new SignalRMessage

@ -25,6 +25,8 @@ namespace Sonarr.Http
public void Handle(ModelEvent<TModel> message) public void Handle(ModelEvent<TModel> message)
{ {
if (!_signalRBroadcaster.IsConnected) return;
if (message.Action == ModelAction.Deleted || message.Action == ModelAction.Sync) if (message.Action == ModelAction.Deleted || message.Action == ModelAction.Sync)
{ {
BroadcastResourceChange(message.Action); BroadcastResourceChange(message.Action);
@ -35,6 +37,8 @@ namespace Sonarr.Http
protected void BroadcastResourceChange(ModelAction action, int id) protected void BroadcastResourceChange(ModelAction action, int id)
{ {
if (!_signalRBroadcaster.IsConnected) return;
if (action == ModelAction.Deleted) if (action == ModelAction.Deleted)
{ {
BroadcastResourceChange(action, new TResource {Id = id}); BroadcastResourceChange(action, new TResource {Id = id});
@ -48,6 +52,8 @@ namespace Sonarr.Http
protected void BroadcastResourceChange(ModelAction action, TResource resource) protected void BroadcastResourceChange(ModelAction action, TResource resource)
{ {
if (!_signalRBroadcaster.IsConnected) return;
if (GetType().Namespace.Contains("V3")) if (GetType().Namespace.Contains("V3"))
{ {
var signalRMessage = new SignalRMessage var signalRMessage = new SignalRMessage
@ -63,6 +69,8 @@ namespace Sonarr.Http
protected void BroadcastResourceChange(ModelAction action) protected void BroadcastResourceChange(ModelAction action)
{ {
if (!_signalRBroadcaster.IsConnected) return;
if (GetType().Namespace.Contains("V3")) if (GetType().Namespace.Contains("V3"))
{ {
var signalRMessage = new SignalRMessage var signalRMessage = new SignalRMessage

Loading…
Cancel
Save