Change task from being canceled to waiting (#118)

This commit is contained in:
rlauuzo 2024-04-16 18:19:05 +02:00 committed by TwistedUmbrellaX
parent 0b77809e9f
commit 0c967180f6
6 changed files with 96 additions and 46 deletions

View File

@ -220,11 +220,11 @@ public class Entrypoint : IServerEntryPoint
/// </summary> /// </summary>
private void StartTimer() private void StartTimer()
{ {
if (Plugin.Instance!.AnalyzerTaskIsRunning) if (Entrypoint.AutomaticTaskState == TaskState.Running)
{ {
_analyzeAgain = true; // Items added during a scan will be included later. _analyzeAgain = true; // Items added during a scan will be included later.
} }
else else if (ScheduledTaskSemaphore.CurrentCount > 0)
{ {
_logger.LogInformation("Media Library changed, analyzis will start soon!"); _logger.LogInformation("Media Library changed, analyzis will start soon!");
_queueTimer.Change(TimeSpan.FromMilliseconds(20000), Timeout.InfiniteTimeSpan); _queueTimer.Change(TimeSpan.FromMilliseconds(20000), Timeout.InfiniteTimeSpan);
@ -252,7 +252,7 @@ public class Entrypoint : IServerEntryPoint
private void PerformAnalysis() private void PerformAnalysis()
{ {
_logger.LogInformation("Timer elapsed - start analyzing"); _logger.LogInformation("Timer elapsed - start analyzing");
Plugin.Instance!.AnalyzerTaskIsRunning = true; _autoTaskCompletEvent.Reset();
using (_cancellationTokenSource = new CancellationTokenSource()) using (_cancellationTokenSource = new CancellationTokenSource())
{ {
@ -303,6 +303,7 @@ public class Entrypoint : IServerEntryPoint
Plugin.Instance!.Configuration.PathRestrictions.Clear(); Plugin.Instance!.Configuration.PathRestrictions.Clear();
Plugin.Instance!.AnalyzerTaskIsRunning = false; Plugin.Instance!.AnalyzerTaskIsRunning = false;
_autoTaskCompletEvent.Set(); _autoTaskCompletEvent.Set();
_cancellationTokenSource = null;
// New item detected, start timer again // New item detected, start timer again
if (_analyzeAgain) if (_analyzeAgain)
@ -316,18 +317,18 @@ public class Entrypoint : IServerEntryPoint
/// <summary> /// <summary>
/// Method to cancel the automatic task. /// Method to cancel the automatic task.
/// </summary> /// </summary>
public static void CancelAutomaticTask() /// <param name="cancellationToken">Cancellation token.</param>
public static void CancelAutomaticTask(CancellationToken cancellationToken)
{ {
if (_cancellationTokenSource != null) if (_cancellationTokenSource != null)
{ {
Plugin.Instance!.Configuration.PathRestrictions.Clear(); if (!_cancellationTokenSource.IsCancellationRequested)
_cancellationTokenSource.Cancel(); {
Plugin.Instance!.Configuration.PathRestrictions.Clear();
_cancellationTokenSource.Cancel();
}
_autoTaskCompletEvent.Wait(); // Wait for the signal _autoTaskCompletEvent.Wait(TimeSpan.FromSeconds(60), cancellationToken); // Wait for the signal
_autoTaskCompletEvent.Reset(); // Reset for the next task
_cancellationTokenSource.Dispose(); // Now safe to dispose
_cancellationTokenSource = null;
} }
} }

View File

@ -149,11 +149,6 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
/// </summary> /// </summary>
public event EventHandler? AutoSkipCreditsChanged; public event EventHandler? AutoSkipCreditsChanged;
/// <summary>
/// Gets or sets a value indicating whether analysis is running.
/// </summary>
public bool AnalyzerTaskIsRunning { get; set; } = false;
/// <summary> /// <summary>
/// Gets the results of fingerprinting all episodes. /// Gets the results of fingerprinting all episodes.
/// </summary> /// </summary>

View File

@ -69,19 +69,22 @@ public class DetectCreditsTask : IScheduledTask
throw new InvalidOperationException("Library manager was null"); throw new InvalidOperationException("Library manager was null");
} }
// abort if analyzer is already running // abort automatic analyzer if running
if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle) if (Entrypoint.AutomaticTaskState == TaskState.Running || Entrypoint.AutomaticTaskState == TaskState.Cancelling)
{
return Task.CompletedTask;
}
else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running)
{ {
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState); _logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
Entrypoint.CancelAutomaticTask(); Entrypoint.CancelAutomaticTask(cancellationToken);
}
ScheduledTaskSemaphore.Wait(-1, cancellationToken);
if (cancellationToken.IsCancellationRequested)
{
ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
} }
_logger.LogInformation("Scheduled Task is starting"); _logger.LogInformation("Scheduled Task is starting");
Plugin.Instance!.AnalyzerTaskIsRunning = true;
var baseCreditAnalyzer = new BaseItemAnalyzerTask( var baseCreditAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Credits, AnalysisMode.Credits,
@ -91,8 +94,7 @@ public class DetectCreditsTask : IScheduledTask
baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken); baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);
Plugin.Instance!.AnalyzerTaskIsRunning = false; ScheduledTaskSemaphore.Release();
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@ -68,19 +68,22 @@ public class DetectIntrosCreditsTask : IScheduledTask
throw new InvalidOperationException("Library manager was null"); throw new InvalidOperationException("Library manager was null");
} }
// abort if analyzer is already running // abort automatic analyzer if running
if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle) if (Entrypoint.AutomaticTaskState == TaskState.Running || Entrypoint.AutomaticTaskState == TaskState.Cancelling)
{
return Task.CompletedTask;
}
else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running)
{ {
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState); _logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
Entrypoint.CancelAutomaticTask(); Entrypoint.CancelAutomaticTask(cancellationToken);
}
ScheduledTaskSemaphore.Wait(-1, cancellationToken);
if (cancellationToken.IsCancellationRequested)
{
ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
} }
_logger.LogInformation("Scheduled Task is starting"); _logger.LogInformation("Scheduled Task is starting");
Plugin.Instance!.AnalyzerTaskIsRunning = true;
var baseIntroAnalyzer = new BaseItemAnalyzerTask( var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction, AnalysisMode.Introduction,
@ -98,8 +101,7 @@ public class DetectIntrosCreditsTask : IScheduledTask
baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken); baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);
Plugin.Instance!.AnalyzerTaskIsRunning = false; ScheduledTaskSemaphore.Release();
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@ -68,19 +68,22 @@ public class DetectIntrosTask : IScheduledTask
throw new InvalidOperationException("Library manager was null"); throw new InvalidOperationException("Library manager was null");
} }
// abort if analyzer is already running // abort automatic analyzer if running
if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle) if (Entrypoint.AutomaticTaskState == TaskState.Running || Entrypoint.AutomaticTaskState == TaskState.Cancelling)
{
return Task.CompletedTask;
}
else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running)
{ {
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState); _logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
Entrypoint.CancelAutomaticTask(); Entrypoint.CancelAutomaticTask(cancellationToken);
}
ScheduledTaskSemaphore.Wait(-1, cancellationToken);
if (cancellationToken.IsCancellationRequested)
{
ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
} }
_logger.LogInformation("Scheduled Task is starting"); _logger.LogInformation("Scheduled Task is starting");
Plugin.Instance!.AnalyzerTaskIsRunning = true;
var baseIntroAnalyzer = new BaseItemAnalyzerTask( var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction, AnalysisMode.Introduction,
@ -90,8 +93,7 @@ public class DetectIntrosTask : IScheduledTask
baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken); baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken);
Plugin.Instance!.AnalyzerTaskIsRunning = false; ScheduledTaskSemaphore.Release();
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@ -0,0 +1,48 @@
using System;
using System.Threading;
namespace ConfusedPolarBear.Plugin.IntroSkipper;
internal sealed class ScheduledTaskSemaphore : IDisposable
{
private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
private ScheduledTaskSemaphore()
{
}
public static int CurrentCount => _semaphore.CurrentCount;
public static bool Wait(int timeout, CancellationToken cancellationToken)
{
return _semaphore.Wait(timeout, cancellationToken);
}
public static int Release()
{
return _semaphore.Release();
}
/// <summary>
/// Dispose.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Protected dispose.
/// </summary>
/// <param name="disposing">Dispose.</param>
private void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
_semaphore.Dispose();
}
}