Add cancellation of automatic tasks from scheduled tasks

This commit is contained in:
rlauu 2024-04-13 17:41:02 +02:00
parent 2e45949e0c
commit 0a9394b244
4 changed files with 108 additions and 44 deletions

View File

@ -24,6 +24,8 @@ public class Entrypoint : IServerEntryPoint
private readonly ILoggerFactory _loggerFactory; private readonly ILoggerFactory _loggerFactory;
private Timer _queueTimer; private Timer _queueTimer;
private bool _analyzeAgain; private bool _analyzeAgain;
private static CancellationTokenSource? _cancellationTokenSource;
private static ManualResetEventSlim _autoTaskCompletEvent = new ManualResetEventSlim(false);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Entrypoint"/> class. /// Initializes a new instance of the <see cref="Entrypoint"/> class.
@ -56,6 +58,24 @@ public class Entrypoint : IServerEntryPoint
Timeout.InfiniteTimeSpan); Timeout.InfiniteTimeSpan);
} }
/// <summary>
/// Gets State of the automatic task.
/// </summary>
public static TaskState AutomaticTaskState
{
get
{
if (_cancellationTokenSource is not null)
{
return _cancellationTokenSource.IsCancellationRequested
? TaskState.Cancelling
: TaskState.Running;
}
return TaskState.Idle;
}
}
/// <summary> /// <summary>
/// Registers event handler. /// Registers event handler.
/// </summary> /// </summary>
@ -208,8 +228,10 @@ public class Entrypoint : IServerEntryPoint
_logger.LogInformation("Timer elapsed - start analyzing"); _logger.LogInformation("Timer elapsed - start analyzing");
Plugin.Instance!.AnalyzerTaskIsRunning = true; Plugin.Instance!.AnalyzerTaskIsRunning = true;
using (_cancellationTokenSource = new CancellationTokenSource())
{
var progress = new Progress<double>(); var progress = new Progress<double>();
var cancellationToken = new CancellationToken(false); var cancellationToken = _cancellationTokenSource.Token;
if (Plugin.Instance!.Configuration.AutoDetectIntros && Plugin.Instance!.Configuration.AutoDetectCredits) if (Plugin.Instance!.Configuration.AutoDetectIntros && Plugin.Instance!.Configuration.AutoDetectCredits)
{ {
@ -250,8 +272,10 @@ public class Entrypoint : IServerEntryPoint
baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken); baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);
} }
}
Plugin.Instance!.AnalyzerTaskIsRunning = false; Plugin.Instance!.AnalyzerTaskIsRunning = false;
_autoTaskCompletEvent.Set();
// New item detected, start timer again // New item detected, start timer again
if (_analyzeAgain) if (_analyzeAgain)
@ -262,6 +286,23 @@ public class Entrypoint : IServerEntryPoint
} }
} }
/// <summary>
/// Method to cancel the automatic task.
/// </summary>
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;
}
}
/// <summary> /// <summary>
/// Dispose. /// Dispose.
/// </summary> /// </summary>
@ -283,6 +324,12 @@ public class Entrypoint : IServerEntryPoint
_libraryManager.ItemUpdated -= OnItemModified; _libraryManager.ItemUpdated -= OnItemModified;
_taskManager.TaskCompleted -= OnLibraryRefresh; _taskManager.TaskCompleted -= OnLibraryRefresh;
if (_cancellationTokenSource != null) // Null Check
{
_cancellationTokenSource.Dispose();
_cancellationTokenSource = null;
}
_queueTimer.Dispose(); _queueTimer.Dispose();
return; return;

View File

@ -70,15 +70,19 @@ public class DetectCreditsTask : IScheduledTask
} }
// abort if analyzer is already running // abort if analyzer is already running
if (Plugin.Instance!.AnalyzerTaskIsRunning) if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle)
{ {
return Task.CompletedTask; 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( var baseCreditAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Credits, AnalysisMode.Credits,
_loggerFactory.CreateLogger<DetectCreditsTask>(), _loggerFactory.CreateLogger<DetectCreditsTask>(),

View File

@ -13,6 +13,8 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper;
/// </summary> /// </summary>
public class DetectIntrosCreditsTask : IScheduledTask public class DetectIntrosCreditsTask : IScheduledTask
{ {
private readonly ILogger<DetectIntrosCreditsTask> _logger;
private readonly ILoggerFactory _loggerFactory; private readonly ILoggerFactory _loggerFactory;
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
@ -22,10 +24,13 @@ public class DetectIntrosCreditsTask : IScheduledTask
/// </summary> /// </summary>
/// <param name="loggerFactory">Logger factory.</param> /// <param name="loggerFactory">Logger factory.</param>
/// <param name="libraryManager">Library manager.</param> /// <param name="libraryManager">Library manager.</param>
/// <param name="logger">Logger.</param>
public DetectIntrosCreditsTask( public DetectIntrosCreditsTask(
ILogger<DetectIntrosCreditsTask> logger,
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory,
ILibraryManager libraryManager) ILibraryManager libraryManager)
{ {
_logger = logger;
_loggerFactory = loggerFactory; _loggerFactory = loggerFactory;
_libraryManager = libraryManager; _libraryManager = libraryManager;
} }
@ -64,15 +69,19 @@ public class DetectIntrosCreditsTask : IScheduledTask
} }
// abort if analyzer is already running // abort if analyzer is already running
if (Plugin.Instance!.AnalyzerTaskIsRunning) if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle)
{ {
return Task.CompletedTask; 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( var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction, AnalysisMode.Introduction,
_loggerFactory.CreateLogger<DetectIntrosCreditsTask>(), _loggerFactory.CreateLogger<DetectIntrosCreditsTask>(),

View File

@ -69,15 +69,19 @@ public class DetectIntrosTask : IScheduledTask
} }
// abort if analyzer is already running // abort if analyzer is already running
if (Plugin.Instance!.AnalyzerTaskIsRunning) if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle)
{ {
return Task.CompletedTask; 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( var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction, AnalysisMode.Introduction,
_loggerFactory.CreateLogger<DetectIntrosTask>(), _loggerFactory.CreateLogger<DetectIntrosTask>(),