Fixed: Various performance improvements for large collections
This commit is contained in:
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\CleanupOrphanedMetadataFilesFixture.cs" />
|
||||
<Compile Include="Housekeeping\Housekeepers\CleanupDownloadClientUnavailablePendingReleasesFixture.cs" />
|
||||
<Compile Include="Housekeeping\Housekeepers\UpdateCleanTitleForSeriesFixture.cs" />
|
||||
<Compile Include="Housekeeping\Housekeepers\CleanupUnusedTagsFixture.cs" />
|
||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedPendingReleasesFixture.cs" />
|
||||
<Compile Include="Housekeeping\Housekeepers\FixFutureDownloadClientStatusTimesFixture.cs" />
|
||||
|
|
|
@ -19,8 +19,12 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
|
|||
|
||||
series.ForEach(s =>
|
||||
{
|
||||
s.CleanTitle = s.CleanTitle.CleanSeriesTitle();
|
||||
_seriesRepository.Update(s);
|
||||
var cleanTitle = s.Title.CleanSeriesTitle();
|
||||
if (s.CleanTitle != cleanTitle)
|
||||
{
|
||||
s.CleanTitle = cleanTitle;
|
||||
_seriesRepository.Update(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace NzbDrone.Core.SeriesStats
|
|||
mapper.AddParameter("currentDate", DateTime.UtcNow);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(GetSelectClause());
|
||||
sb.AppendLine(GetSelectClause(false));
|
||||
sb.AppendLine(GetEpisodeFilesJoin());
|
||||
sb.AppendLine(GetGroupByClause());
|
||||
var queryText = sb.ToString();
|
||||
|
@ -43,16 +43,15 @@ namespace NzbDrone.Core.SeriesStats
|
|||
mapper.AddParameter("seriesId", seriesId);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(GetSelectClause());
|
||||
sb.AppendLine(GetSelectClause(true));
|
||||
sb.AppendLine(GetEpisodeFilesJoin());
|
||||
sb.AppendLine("WHERE Episodes.SeriesId = @seriesId");
|
||||
sb.AppendLine(GetGroupByClause());
|
||||
var queryText = sb.ToString();
|
||||
|
||||
return mapper.Query<SeasonStatistics>(queryText);
|
||||
}
|
||||
|
||||
private string GetSelectClause()
|
||||
private string GetSelectClause(bool series)
|
||||
{
|
||||
return @"SELECT Episodes.*, SUM(EpisodeFiles.Size) as SizeOnDisk FROM
|
||||
(SELECT
|
||||
|
@ -64,7 +63,8 @@ namespace NzbDrone.Core.SeriesStats
|
|||
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,
|
||||
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";
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace NzbDrone.SignalR
|
|||
{
|
||||
public interface IBroadcastSignalRMessage
|
||||
{
|
||||
bool IsConnected { get; }
|
||||
void BroadcastMessage(SignalRMessage message);
|
||||
}
|
||||
|
||||
|
@ -20,7 +21,8 @@ namespace NzbDrone.SignalR
|
|||
private IPersistentConnectionContext Context => ((ConnectionManager)GlobalHost.ConnectionManager).GetConnection(GetType());
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -28,6 +30,17 @@ namespace NzbDrone.SignalR
|
|||
_messageHistory = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_connections)
|
||||
{
|
||||
return _connections.Count != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void BroadcastMessage(SignalRMessage message)
|
||||
{
|
||||
|
@ -59,14 +72,34 @@ namespace NzbDrone.SignalR
|
|||
|
||||
protected override Task OnConnected(IRequest request, string connectionId)
|
||||
{
|
||||
lock (_connections)
|
||||
{
|
||||
_connections.Add(connectionId);
|
||||
}
|
||||
|
||||
return SendVersion(connectionId);
|
||||
}
|
||||
|
||||
protected override Task OnReconnected(IRequest request, string connectionId)
|
||||
{
|
||||
lock (_connections)
|
||||
{
|
||||
_connections.Add(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)
|
||||
{
|
||||
return Context.Connection.Send(connectionId, new SignalRMessage
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace Sonarr.Http
|
|||
|
||||
public void Handle(ModelEvent<TModel> message)
|
||||
{
|
||||
if (!_signalRBroadcaster.IsConnected) return;
|
||||
|
||||
if (message.Action == ModelAction.Deleted || message.Action == ModelAction.Sync)
|
||||
{
|
||||
BroadcastResourceChange(message.Action);
|
||||
|
@ -35,6 +37,8 @@ namespace Sonarr.Http
|
|||
|
||||
protected void BroadcastResourceChange(ModelAction action, int id)
|
||||
{
|
||||
if (!_signalRBroadcaster.IsConnected) return;
|
||||
|
||||
if (action == ModelAction.Deleted)
|
||||
{
|
||||
BroadcastResourceChange(action, new TResource {Id = id});
|
||||
|
@ -48,6 +52,8 @@ namespace Sonarr.Http
|
|||
|
||||
protected void BroadcastResourceChange(ModelAction action, TResource resource)
|
||||
{
|
||||
if (!_signalRBroadcaster.IsConnected) return;
|
||||
|
||||
if (GetType().Namespace.Contains("V3"))
|
||||
{
|
||||
var signalRMessage = new SignalRMessage
|
||||
|
@ -63,6 +69,8 @@ namespace Sonarr.Http
|
|||
|
||||
protected void BroadcastResourceChange(ModelAction action)
|
||||
{
|
||||
if (!_signalRBroadcaster.IsConnected) return;
|
||||
|
||||
if (GetType().Namespace.Contains("V3"))
|
||||
{
|
||||
var signalRMessage = new SignalRMessage
|
||||
|
|
Loading…
Reference in New Issue