From 676215c08f3fc57edc623852cab1c6a04c09469c Mon Sep 17 00:00:00 2001 From: rlauu <46294892+rlauu@users.noreply.github.com> Date: Sat, 13 Apr 2024 16:34:58 +0200 Subject: [PATCH] Make scheduled tasks cancel automatic tasks --- .../Entrypoint.cs | 117 ++++++++++++------ .../ScheduledTasks/DetectCreditsTask.cs | 10 +- .../ScheduledTasks/DetectIntrosCreditsTask.cs | 15 ++- .../ScheduledTasks/DetectIntrosTask.cs | 10 +- 4 files changed, 108 insertions(+), 44 deletions(-) diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs index 1195e54..eb29368 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs @@ -25,6 +25,8 @@ public class Entrypoint : IHostedService, IDisposable private readonly ILoggerFactory _loggerFactory; private Timer _queueTimer; private bool _analyzeAgain; + private static CancellationTokenSource? _cancellationTokenSource; + private static ManualResetEventSlim _autoTaskCompletEvent = new ManualResetEventSlim(false); /// /// Initializes a new instance of the class. @@ -57,6 +59,24 @@ public class Entrypoint : IHostedService, IDisposable Timeout.InfiniteTimeSpan); } + /// + /// Gets State of the automatic task. + /// + public static TaskState AutomaticTaskState + { + get + { + if (_cancellationTokenSource is not null) + { + return _cancellationTokenSource.IsCancellationRequested + ? TaskState.Cancelling + : TaskState.Running; + } + + return TaskState.Idle; + } + } + /// public Task StartAsync(CancellationToken cancellationToken) { @@ -91,6 +111,12 @@ public class Entrypoint : IHostedService, IDisposable // Stop the timer _queueTimer.Change(Timeout.Infinite, 0); + if (_cancellationTokenSource != null) // Null Check + { + _cancellationTokenSource.Dispose(); + _cancellationTokenSource = null; + } + return Task.CompletedTask; } @@ -219,50 +245,54 @@ public class Entrypoint : IHostedService, IDisposable _logger.LogInformation("Timer elapsed - start analyzing"); Plugin.Instance!.AnalyzerTaskIsRunning = true; - var progress = new Progress(); - var cancellationToken = new CancellationToken(false); - - if (Plugin.Instance!.Configuration.AutoDetectIntros && Plugin.Instance!.Configuration.AutoDetectCredits) + using (_cancellationTokenSource = new CancellationTokenSource()) { - // This is where we can optimize a single scan - var baseIntroAnalyzer = new BaseItemAnalyzerTask( - AnalysisMode.Introduction, - _loggerFactory.CreateLogger(), - _loggerFactory, - _libraryManager); + var progress = new Progress(); + var cancellationToken = _cancellationTokenSource.Token; - baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken); + if (Plugin.Instance!.Configuration.AutoDetectIntros && Plugin.Instance!.Configuration.AutoDetectCredits) + { + // This is where we can optimize a single scan + var baseIntroAnalyzer = new BaseItemAnalyzerTask( + AnalysisMode.Introduction, + _loggerFactory.CreateLogger(), + _loggerFactory, + _libraryManager); - var baseCreditAnalyzer = new BaseItemAnalyzerTask( - AnalysisMode.Credits, - _loggerFactory.CreateLogger(), - _loggerFactory, - _libraryManager); + baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken); - baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken); - } - else if (Plugin.Instance!.Configuration.AutoDetectIntros) - { - var baseIntroAnalyzer = new BaseItemAnalyzerTask( - AnalysisMode.Introduction, - _loggerFactory.CreateLogger(), - _loggerFactory, - _libraryManager); + var baseCreditAnalyzer = new BaseItemAnalyzerTask( + AnalysisMode.Credits, + _loggerFactory.CreateLogger(), + _loggerFactory, + _libraryManager); - baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken); - } - else if (Plugin.Instance!.Configuration.AutoDetectCredits) - { - var baseCreditAnalyzer = new BaseItemAnalyzerTask( - AnalysisMode.Credits, - _loggerFactory.CreateLogger(), - _loggerFactory, - _libraryManager); + baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken); + } + else if (Plugin.Instance!.Configuration.AutoDetectIntros) + { + var baseIntroAnalyzer = new BaseItemAnalyzerTask( + AnalysisMode.Introduction, + _loggerFactory.CreateLogger(), + _loggerFactory, + _libraryManager); - baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken); + baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken); + } + else if (Plugin.Instance!.Configuration.AutoDetectCredits) + { + var baseCreditAnalyzer = new BaseItemAnalyzerTask( + AnalysisMode.Credits, + _loggerFactory.CreateLogger(), + _loggerFactory, + _libraryManager); + + baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken); + } } Plugin.Instance!.AnalyzerTaskIsRunning = false; + _autoTaskCompletEvent.Set(); // New item detected, start timer again if (_analyzeAgain) @@ -273,6 +303,23 @@ public class Entrypoint : IHostedService, IDisposable } } + /// + /// Method to cancel the automatic task. + /// + public static void CancelAutomaticTask() + { + if (_cancellationTokenSource != null) + { + _cancellationTokenSource.Cancel(); + + _autoTaskCompletEvent.Wait(); // Wait for the signal + _autoTaskCompletEvent.Reset(); // Reset for the next task + + _cancellationTokenSource.Dispose(); // Now safe to dispose + _cancellationTokenSource = null; + } + } + /// /// Dispose. /// diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectCreditsTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectCreditsTask.cs index e02d960..bacb457 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectCreditsTask.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectCreditsTask.cs @@ -70,15 +70,19 @@ public class DetectCreditsTask : IScheduledTask } // abort if analyzer is already running - if (Plugin.Instance!.AnalyzerTaskIsRunning) + if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle) { return Task.CompletedTask; } - else + else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running) { - Plugin.Instance!.AnalyzerTaskIsRunning = true; + _logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState); + Entrypoint.CancelAutomaticTask(); } + _logger.LogInformation("Scheduled Task is starting"); + Plugin.Instance!.AnalyzerTaskIsRunning = true; + var baseCreditAnalyzer = new BaseItemAnalyzerTask( AnalysisMode.Credits, _loggerFactory.CreateLogger(), diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosCreditsTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosCreditsTask.cs index 913d87c..f58472c 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosCreditsTask.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosCreditsTask.cs @@ -13,6 +13,8 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper; /// public class DetectIntrosCreditsTask : IScheduledTask { + private readonly ILogger _logger; + private readonly ILoggerFactory _loggerFactory; private readonly ILibraryManager _libraryManager; @@ -22,10 +24,13 @@ public class DetectIntrosCreditsTask : IScheduledTask /// /// Logger factory. /// Library manager. + /// Logger. public DetectIntrosCreditsTask( + ILogger logger, ILoggerFactory loggerFactory, ILibraryManager libraryManager) { + _logger = logger; _loggerFactory = loggerFactory; _libraryManager = libraryManager; } @@ -64,15 +69,19 @@ public class DetectIntrosCreditsTask : IScheduledTask } // abort if analyzer is already running - if (Plugin.Instance!.AnalyzerTaskIsRunning) + if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle) { return Task.CompletedTask; } - else + else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running) { - Plugin.Instance!.AnalyzerTaskIsRunning = true; + _logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState); + Entrypoint.CancelAutomaticTask(); } + _logger.LogInformation("Scheduled Task is starting"); + Plugin.Instance!.AnalyzerTaskIsRunning = true; + var baseIntroAnalyzer = new BaseItemAnalyzerTask( AnalysisMode.Introduction, _loggerFactory.CreateLogger(), diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosTask.cs index b0964f7..c92f800 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosTask.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/DetectIntrosTask.cs @@ -69,15 +69,19 @@ public class DetectIntrosTask : IScheduledTask } // abort if analyzer is already running - if (Plugin.Instance!.AnalyzerTaskIsRunning) + if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle) { return Task.CompletedTask; } - else + else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running) { - Plugin.Instance!.AnalyzerTaskIsRunning = true; + _logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState); + Entrypoint.CancelAutomaticTask(); } + _logger.LogInformation("Scheduled Task is starting"); + Plugin.Instance!.AnalyzerTaskIsRunning = true; + var baseIntroAnalyzer = new BaseItemAnalyzerTask( AnalysisMode.Introduction, _loggerFactory.CreateLogger(),