Remove analysis statistics
This commit is contained in:
parent
8953b4087f
commit
991283387c
@ -1,22 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace ConfusedPolarBear.Plugin.IntroSkipper.Tests;
|
|
||||||
|
|
||||||
public class TestStatistics
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void TestTSISerialization()
|
|
||||||
{
|
|
||||||
var expected = "\"TotalAnalyzedEpisodes\":42,";
|
|
||||||
|
|
||||||
var stats = new AnalysisStatistics();
|
|
||||||
stats.TotalAnalyzedEpisodes.Add(42);
|
|
||||||
|
|
||||||
var actual = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(stats));
|
|
||||||
|
|
||||||
Assert.Contains(expected, actual, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
@ -258,12 +258,6 @@
|
|||||||
<textarea id="supportBundle" rows="20" cols="75" readonly></textarea>
|
<textarea id="supportBundle" rows="20" cols="75" readonly></textarea>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details id="statistics">
|
|
||||||
<summary>Analysis Statistics (experimental)</summary>
|
|
||||||
|
|
||||||
<pre id="statisticsText" style="font-size: larger"></p>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details id="visualizer">
|
<details id="visualizer">
|
||||||
<summary>Advanced</summary>
|
<summary>Advanced</summary>
|
||||||
|
|
||||||
@ -372,7 +366,6 @@
|
|||||||
|
|
||||||
// settings elements
|
// settings elements
|
||||||
var visualizer = document.querySelector("details#visualizer");
|
var visualizer = document.querySelector("details#visualizer");
|
||||||
var statistics = document.querySelector("details#statistics");
|
|
||||||
var support = document.querySelector("details#support");
|
var support = document.querySelector("details#support");
|
||||||
var btnEraseTimestamps = document.querySelector("button#btnEraseTimestamps");
|
var btnEraseTimestamps = document.querySelector("button#btnEraseTimestamps");
|
||||||
|
|
||||||
@ -470,59 +463,6 @@
|
|||||||
Dashboard.alert("Press Ctrl+C to copy support bundle");
|
Dashboard.alert("Press Ctrl+C to copy support bundle");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function statisticsToggled() {
|
|
||||||
if (!statistics.open) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blank any old statistics
|
|
||||||
const text = document.querySelector("pre#statisticsText");
|
|
||||||
text.textContent = "All CPU times are displayed as seconds.\n\n";
|
|
||||||
|
|
||||||
Dashboard.showLoadingMsg();
|
|
||||||
|
|
||||||
// Load the statistics from the server
|
|
||||||
let stats = await getJson("Intros/Statistics");
|
|
||||||
|
|
||||||
// Select which fields to print and label them with more friendly descriptions
|
|
||||||
let fields = "TotalTaskTime,TotalCPUTime,FingerprintCPUTime,FirstPassCPUTime,SecondPassCPUTime," +
|
|
||||||
"IndexSearches,QuickScans,FullScans,TotalQueuedEpisodes";
|
|
||||||
|
|
||||||
let friendlyNames = {
|
|
||||||
TotalTaskTime: "Total task time",
|
|
||||||
TotalCPUTime: "Total CPU time",
|
|
||||||
FingerprintCPUTime: "Fingerprint CPU time",
|
|
||||||
FirstPassCPUTime: "First pass CPU time",
|
|
||||||
SecondPassCPUTime: "Second pass CPU time",
|
|
||||||
IndexSearches: "Index searches",
|
|
||||||
QuickScans: "Quick scans",
|
|
||||||
FullScans: "Full scans",
|
|
||||||
TotalQueuedEpisodes: "Episodes queued",
|
|
||||||
};
|
|
||||||
|
|
||||||
// Print all friendly names and data points
|
|
||||||
for (var f of fields.split(",")) {
|
|
||||||
let name = friendlyNames[f].padEnd(25);
|
|
||||||
let value = stats[f];
|
|
||||||
|
|
||||||
// If this statistic is a measure of CPU time, divide by 1,000 to turn milliseconds into seconds.
|
|
||||||
if (name.includes("time")) {
|
|
||||||
value = Math.round(value / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
text.textContent += name + value + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the percentage of time (to two decimal places) spent waiting for fingerprints
|
|
||||||
const percentWait = Math.round((stats.FingerprintCPUTime * 10_000) / stats.TotalCPUTime) / 100;
|
|
||||||
|
|
||||||
// Breakdown CPU time by analysis component
|
|
||||||
text.textContent += "\nCPU time breakdown:\n";
|
|
||||||
text.textContent += "Fingerprint generation " + percentWait + "%\n";
|
|
||||||
|
|
||||||
Dashboard.hideLoadingMsg();
|
|
||||||
}
|
|
||||||
|
|
||||||
// show changed, populate seasons
|
// show changed, populate seasons
|
||||||
async function showChanged() {
|
async function showChanged() {
|
||||||
clearSelect(selectSeason);
|
clearSelect(selectSeason);
|
||||||
@ -752,7 +692,6 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
visualizer.addEventListener("toggle", visualizerToggled);
|
visualizer.addEventListener("toggle", visualizerToggled);
|
||||||
statistics.addEventListener("toggle", statisticsToggled);
|
|
||||||
support.addEventListener("toggle", supportToggled);
|
support.addEventListener("toggle", supportToggled);
|
||||||
txtOffset.addEventListener("change", renderTroubleshooter);
|
txtOffset.addEventListener("change", renderTroubleshooter);
|
||||||
selectShow.addEventListener("change", showChanged);
|
selectShow.addEventListener("change", showChanged);
|
||||||
|
@ -166,17 +166,6 @@ public class VisualizationController : ControllerBase
|
|||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the statistics for the most recent analysis.
|
|
||||||
/// </summary>
|
|
||||||
/// <response code="200">Analysis statistics.</response>
|
|
||||||
/// <returns>AnalysisStatistics.</returns>
|
|
||||||
[HttpGet("Statistics")]
|
|
||||||
public ActionResult<AnalysisStatistics> GetAnalysisStatistics()
|
|
||||||
{
|
|
||||||
return Plugin.Instance!.AnalysisStatistics;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetSeasonName(QueuedEpisode episode)
|
private string GetSeasonName(QueuedEpisode episode)
|
||||||
{
|
{
|
||||||
return "Season " + episode.SeasonNumber.ToString(CultureInfo.InvariantCulture);
|
return "Season " + episode.SeasonNumber.ToString(CultureInfo.InvariantCulture);
|
||||||
|
@ -1,128 +0,0 @@
|
|||||||
namespace ConfusedPolarBear.Plugin.IntroSkipper;
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Detailed statistics about the last analysis operation performed. All times are represented as milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
public class AnalysisStatistics
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of episodes that have been analyzed so far.
|
|
||||||
/// </summary>
|
|
||||||
public ThreadSafeInteger TotalAnalyzedEpisodes { get; } = new ThreadSafeInteger();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the number of episodes that need to be analyzed.
|
|
||||||
/// </summary>
|
|
||||||
public int TotalQueuedEpisodes { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of times an index search successfully located a pair of introductions.
|
|
||||||
/// </summary>
|
|
||||||
public ThreadSafeInteger IndexSearches { get; } = new ThreadSafeInteger();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the total CPU time spent waiting for audio fingerprints to be generated.
|
|
||||||
/// </summary>
|
|
||||||
public ThreadSafeInteger FingerprintCPUTime { get; } = new ThreadSafeInteger();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the total CPU time spent analyzing fingerprints.
|
|
||||||
/// </summary>
|
|
||||||
public ThreadSafeInteger AnalysisCPUTime { get; } = new ThreadSafeInteger();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the total task runtime across all threads.
|
|
||||||
/// </summary>
|
|
||||||
public ThreadSafeInteger TotalCPUTime { get; } = new ThreadSafeInteger();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the total task runtime as measured by a clock.
|
|
||||||
/// </summary>
|
|
||||||
public ThreadSafeInteger TotalTaskTime { get; } = new ThreadSafeInteger();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Convenience wrapper around a thread safe integer.
|
|
||||||
/// </summary>
|
|
||||||
[JsonConverter(typeof(ThreadSafeIntegerJsonConverter))]
|
|
||||||
public class ThreadSafeInteger
|
|
||||||
{
|
|
||||||
private int value = 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current value stored by this integer.
|
|
||||||
/// </summary>
|
|
||||||
public int Value
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Increment the value of this integer by 1.
|
|
||||||
/// </summary>
|
|
||||||
public void Increment()
|
|
||||||
{
|
|
||||||
Add(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds the total milliseconds elapsed since a start time.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="start">Start time.</param>
|
|
||||||
public void AddDuration(DateTime start)
|
|
||||||
{
|
|
||||||
if (start == DateTime.MinValue)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var elapsed = DateTime.Now.Subtract(start);
|
|
||||||
Add((int)elapsed.TotalMilliseconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds the provided amount to this integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="amount">Amount to add.</param>
|
|
||||||
public void Add(int amount)
|
|
||||||
{
|
|
||||||
Interlocked.Add(ref value, amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Serialize thread safe integers to a regular integer (instead of an object with a Value property).
|
|
||||||
/// </summary>
|
|
||||||
public class ThreadSafeIntegerJsonConverter : JsonConverter<ThreadSafeInteger>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Deserialization of TSIs is not supported and will always throw a NotSupportedException.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="reader">Reader.</param>
|
|
||||||
/// <param name="typeToConvert">Type.</param>
|
|
||||||
/// <param name="options">Options.</param>
|
|
||||||
/// <returns>Never returns.</returns>
|
|
||||||
public override ThreadSafeInteger? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Serialize the provided TSI.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="writer">Writer.</param>
|
|
||||||
/// <param name="value">TSI.</param>
|
|
||||||
/// <param name="options">Options.</param>
|
|
||||||
public override void Write(Utf8JsonWriter writer, ThreadSafeInteger value, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
writer.WriteNumberValue(value.Value);
|
|
||||||
}
|
|
||||||
}
|
|
@ -80,11 +80,6 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int TotalQueued { get; set; }
|
public int TotalQueued { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the statistics from the most recent analysis run.
|
|
||||||
/// </summary>
|
|
||||||
public AnalysisStatistics AnalysisStatistics { get; set; } = new AnalysisStatistics();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the directory to cache fingerprints in.
|
/// Gets the directory to cache fingerprints in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -31,11 +31,6 @@ public class AnalyzeEpisodesTask : IScheduledTask
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _introsLock = new object();
|
private readonly object _introsLock = new object();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Statistics for the currently running analysis task.
|
|
||||||
/// </summary>
|
|
||||||
private AnalysisStatistics analysisStatistics = new AnalysisStatistics();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Minimum duration of similar audio that will be considered an introduction.
|
/// Minimum duration of similar audio that will be considered an introduction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -133,8 +128,6 @@ public class AnalyzeEpisodesTask : IScheduledTask
|
|||||||
};
|
};
|
||||||
|
|
||||||
var taskStart = DateTime.Now;
|
var taskStart = DateTime.Now;
|
||||||
analysisStatistics = new AnalysisStatistics();
|
|
||||||
analysisStatistics.TotalQueuedEpisodes = Plugin.Instance!.TotalQueued;
|
|
||||||
|
|
||||||
minimumIntroDuration = Plugin.Instance!.Configuration.MinimumIntroDuration;
|
minimumIntroDuration = Plugin.Instance!.Configuration.MinimumIntroDuration;
|
||||||
|
|
||||||
@ -186,15 +179,8 @@ public class AnalyzeEpisodesTask : IScheduledTask
|
|||||||
}
|
}
|
||||||
|
|
||||||
progress.Report((totalProcessed * 100) / Plugin.Instance!.TotalQueued);
|
progress.Report((totalProcessed * 100) / Plugin.Instance!.TotalQueued);
|
||||||
|
|
||||||
analysisStatistics.TotalCPUTime.AddDuration(workerStart);
|
|
||||||
Plugin.Instance!.AnalysisStatistics = analysisStatistics;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update analysis statistics
|
|
||||||
analysisStatistics.TotalTaskTime.AddDuration(taskStart);
|
|
||||||
Plugin.Instance!.AnalysisStatistics = analysisStatistics;
|
|
||||||
|
|
||||||
// Turn the regenerate EDL flag off after the scan completes.
|
// Turn the regenerate EDL flag off after the scan completes.
|
||||||
if (Plugin.Instance!.Configuration.RegenerateEdlFiles)
|
if (Plugin.Instance!.Configuration.RegenerateEdlFiles)
|
||||||
{
|
{
|
||||||
@ -385,8 +371,6 @@ public class AnalyzeEpisodesTask : IScheduledTask
|
|||||||
if (lhsRanges.Count > 0)
|
if (lhsRanges.Count > 0)
|
||||||
{
|
{
|
||||||
_logger.LogTrace("Index search successful");
|
_logger.LogTrace("Index search successful");
|
||||||
analysisStatistics.IndexSearches.Increment();
|
|
||||||
analysisStatistics.AnalysisCPUTime.AddDuration(start);
|
|
||||||
|
|
||||||
return GetLongestTimeRange(lhsId, lhsRanges, rhsId, rhsRanges);
|
return GetLongestTimeRange(lhsId, lhsRanges, rhsId, rhsRanges);
|
||||||
}
|
}
|
||||||
@ -396,8 +380,6 @@ public class AnalyzeEpisodesTask : IScheduledTask
|
|||||||
lhsId,
|
lhsId,
|
||||||
rhsId);
|
rhsId);
|
||||||
|
|
||||||
analysisStatistics.AnalysisCPUTime.AddDuration(start);
|
|
||||||
|
|
||||||
return (new Intro(lhsId), new Intro(rhsId));
|
return (new Intro(lhsId), new Intro(rhsId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user