Skip to content

Commit

Permalink
Change task from being canceled to waiting (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
rlauuzo authored and AbandonedCart committed Apr 16, 2024
1 parent 0b77809 commit 0c96718
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 43 deletions.
23 changes: 12 additions & 11 deletions ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,11 @@ private void OnLibraryRefresh(object? sender, TaskCompletionEventArgs eventArgs)
/// </summary>
private void StartTimer()
{
if (Plugin.Instance!.AnalyzerTaskIsRunning)
if (Entrypoint.AutomaticTaskState == TaskState.Running)
{
_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!");
_queueTimer.Change(TimeSpan.FromMilliseconds(20000), Timeout.InfiniteTimeSpan);
Expand Down Expand Up @@ -252,7 +252,7 @@ private void OnTimerCallback(object? state)
private void PerformAnalysis()
{
_logger.LogInformation("Timer elapsed - start analyzing");
Plugin.Instance!.AnalyzerTaskIsRunning = true;
_autoTaskCompletEvent.Reset();

using (_cancellationTokenSource = new CancellationTokenSource())
{
Expand Down Expand Up @@ -303,6 +303,7 @@ private void PerformAnalysis()
Plugin.Instance!.Configuration.PathRestrictions.Clear();
Plugin.Instance!.AnalyzerTaskIsRunning = false;

Check failure on line 304 in ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs

View workflow job for this annotation

GitHub Actions / build

'Plugin' does not contain a definition for 'AnalyzerTaskIsRunning' and no accessible extension method 'AnalyzerTaskIsRunning' accepting a first argument of type 'Plugin' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 304 in ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs

View workflow job for this annotation

GitHub Actions / build

'Plugin' does not contain a definition for 'AnalyzerTaskIsRunning' and no accessible extension method 'AnalyzerTaskIsRunning' accepting a first argument of type 'Plugin' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 304 in ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'Plugin' does not contain a definition for 'AnalyzerTaskIsRunning' and no accessible extension method 'AnalyzerTaskIsRunning' accepting a first argument of type 'Plugin' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 304 in ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'Plugin' does not contain a definition for 'AnalyzerTaskIsRunning' and no accessible extension method 'AnalyzerTaskIsRunning' accepting a first argument of type 'Plugin' could be found (are you missing a using directive or an assembly reference?)
_autoTaskCompletEvent.Set();
_cancellationTokenSource = null;

// New item detected, start timer again
if (_analyzeAgain)
Expand All @@ -316,18 +317,18 @@ private void PerformAnalysis()
/// <summary>
/// Method to cancel the automatic task.
/// </summary>
public static void CancelAutomaticTask()
/// <param name="cancellationToken">Cancellation token.</param>
public static void CancelAutomaticTask(CancellationToken cancellationToken)
{
if (_cancellationTokenSource != null)
{
Plugin.Instance!.Configuration.PathRestrictions.Clear();
_cancellationTokenSource.Cancel();

_autoTaskCompletEvent.Wait(); // Wait for the signal
_autoTaskCompletEvent.Reset(); // Reset for the next task
if (!_cancellationTokenSource.IsCancellationRequested)
{
Plugin.Instance!.Configuration.PathRestrictions.Clear();
_cancellationTokenSource.Cancel();
}

_cancellationTokenSource.Dispose(); // Now safe to dispose
_cancellationTokenSource = null;
_autoTaskCompletEvent.Wait(TimeSpan.FromSeconds(60), cancellationToken); // Wait for the signal
}
}

Expand Down
5 changes: 0 additions & 5 deletions ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,6 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
/// </summary>
public event EventHandler? AutoSkipCreditsChanged;

/// <summary>
/// Gets or sets a value indicating whether analysis is running.
/// </summary>
public bool AnalyzerTaskIsRunning { get; set; } = false;

/// <summary>
/// Gets the results of fingerprinting all episodes.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,22 @@ public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellat
throw new InvalidOperationException("Library manager was null");
}

// abort if analyzer is already running
if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle)
// abort automatic analyzer if running
if (Entrypoint.AutomaticTaskState == TaskState.Running || Entrypoint.AutomaticTaskState == TaskState.Cancelling)
{
return Task.CompletedTask;
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
Entrypoint.CancelAutomaticTask(cancellationToken);
}
else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running)

ScheduledTaskSemaphore.Wait(-1, cancellationToken);

if (cancellationToken.IsCancellationRequested)
{
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
Entrypoint.CancelAutomaticTask();
ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
}

_logger.LogInformation("Scheduled Task is starting");
Plugin.Instance!.AnalyzerTaskIsRunning = true;

var baseCreditAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Credits,
Expand All @@ -91,8 +94,7 @@ public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellat

baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);

Plugin.Instance!.AnalyzerTaskIsRunning = false;

ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,22 @@ public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellat
throw new InvalidOperationException("Library manager was null");
}

// abort if analyzer is already running
if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle)
// abort automatic analyzer if running
if (Entrypoint.AutomaticTaskState == TaskState.Running || Entrypoint.AutomaticTaskState == TaskState.Cancelling)
{
return Task.CompletedTask;
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
Entrypoint.CancelAutomaticTask(cancellationToken);
}
else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running)

ScheduledTaskSemaphore.Wait(-1, cancellationToken);

if (cancellationToken.IsCancellationRequested)
{
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
Entrypoint.CancelAutomaticTask();
ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
}

_logger.LogInformation("Scheduled Task is starting");
Plugin.Instance!.AnalyzerTaskIsRunning = true;

var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction,
Expand All @@ -98,8 +101,7 @@ public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellat

baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);

Plugin.Instance!.AnalyzerTaskIsRunning = false;

ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,22 @@ public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellat
throw new InvalidOperationException("Library manager was null");
}

// abort if analyzer is already running
if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Idle)
// abort automatic analyzer if running
if (Entrypoint.AutomaticTaskState == TaskState.Running || Entrypoint.AutomaticTaskState == TaskState.Cancelling)
{
return Task.CompletedTask;
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
Entrypoint.CancelAutomaticTask(cancellationToken);
}
else if (Plugin.Instance!.AnalyzerTaskIsRunning && Entrypoint.AutomaticTaskState == TaskState.Running)

ScheduledTaskSemaphore.Wait(-1, cancellationToken);

if (cancellationToken.IsCancellationRequested)
{
_logger.LogInformation("Automatic Task is {0} and will be canceled.", Entrypoint.AutomaticTaskState);
Entrypoint.CancelAutomaticTask();
ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
}

_logger.LogInformation("Scheduled Task is starting");
Plugin.Instance!.AnalyzerTaskIsRunning = true;

var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction,
Expand All @@ -90,8 +93,7 @@ public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellat

baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken);

Plugin.Instance!.AnalyzerTaskIsRunning = false;

ScheduledTaskSemaphore.Release();
return Task.CompletedTask;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
}

0 comments on commit 0c96718

Please sign in to comment.