diff --git a/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs b/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs index 09c470884..94daedf0d 100644 --- a/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs +++ b/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs @@ -11,6 +11,7 @@ using ErsatzTV.Core.Interfaces.Jellyfin; using ErsatzTV.Core.Interfaces.Locking; using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Plex; +using ErsatzTV.Core.Interfaces.Troubleshooting; using ErsatzTV.Core.Notifications; using ErsatzTV.FFmpeg; using ErsatzTV.FFmpeg.State; @@ -34,6 +35,7 @@ public class PrepareTroubleshootingPlaybackHandler( ISongVideoGenerator songVideoGenerator, IWatermarkSelector watermarkSelector, IEntityLocker entityLocker, + ITroubleshootingPlaybackStatusStore statusStore, IMediator mediator, LoggingLevelSwitches loggingLevelSwitches, ILogger logger) @@ -68,6 +70,7 @@ public class PrepareTroubleshootingPlaybackHandler( } entityLocker.LockTroubleshootingPlayback(); + statusStore.Reset(); localFileSystem.EnsureFolderExists(FileSystemLayout.TranscodeTroubleshootingFolder); localFileSystem.EmptyFolder(FileSystemLayout.TranscodeTroubleshootingFolder); @@ -166,6 +169,7 @@ public class PrepareTroubleshootingPlaybackHandler( } entityLocker.LockTroubleshootingPlayback(); + statusStore.Reset(); localFileSystem.EnsureFolderExists(FileSystemLayout.TranscodeTroubleshootingFolder); localFileSystem.EmptyFolder(FileSystemLayout.TranscodeTroubleshootingFolder); diff --git a/ErsatzTV.Application/Troubleshooting/RecordTroubleshootingPlaybackStatusHandler.cs b/ErsatzTV.Application/Troubleshooting/RecordTroubleshootingPlaybackStatusHandler.cs new file mode 100644 index 000000000..47438511e --- /dev/null +++ b/ErsatzTV.Application/Troubleshooting/RecordTroubleshootingPlaybackStatusHandler.cs @@ -0,0 +1,14 @@ +using ErsatzTV.Core.Interfaces.Troubleshooting; +using ErsatzTV.Core.Notifications; + +namespace ErsatzTV.Application.Troubleshooting; + +public class RecordTroubleshootingPlaybackStatusHandler(ITroubleshootingPlaybackStatusStore statusStore) + : INotificationHandler +{ + public Task Handle(PlaybackTroubleshootingCompletedNotification notification, CancellationToken cancellationToken) + { + statusStore.RecordCompletion(notification.ExitCode, notification.MaybeSpeed); + return Task.CompletedTask; + } +} diff --git a/ErsatzTV.Core/Interfaces/Troubleshooting/ITroubleshootingPlaybackStatusStore.cs b/ErsatzTV.Core/Interfaces/Troubleshooting/ITroubleshootingPlaybackStatusStore.cs new file mode 100644 index 000000000..0bb6d1a8b --- /dev/null +++ b/ErsatzTV.Core/Interfaces/Troubleshooting/ITroubleshootingPlaybackStatusStore.cs @@ -0,0 +1,16 @@ +using ErsatzTV.Core.Troubleshooting; + +namespace ErsatzTV.Core.Interfaces.Troubleshooting; + +// Records the outcome of the most recent troubleshooting playback session so the SPA can poll +// for completion (the legacy Blazor page instead subscribed to an in-process notification). The +// store is reset when a new session starts (see PrepareTroubleshootingPlaybackHandler) and written +// by the PlaybackTroubleshootingCompletedNotification handler. +public interface ITroubleshootingPlaybackStatusStore +{ + Option CurrentResult { get; } + + void Reset(); + + void RecordCompletion(int exitCode, Option speed); +} diff --git a/ErsatzTV.Core/Troubleshooting/TroubleshootingPlaybackResult.cs b/ErsatzTV.Core/Troubleshooting/TroubleshootingPlaybackResult.cs new file mode 100644 index 000000000..0b280099c --- /dev/null +++ b/ErsatzTV.Core/Troubleshooting/TroubleshootingPlaybackResult.cs @@ -0,0 +1,3 @@ +namespace ErsatzTV.Core.Troubleshooting; + +public record TroubleshootingPlaybackResult(int ExitCode, Option Speed); diff --git a/ErsatzTV.Core/Troubleshooting/TroubleshootingPlaybackStatusStore.cs b/ErsatzTV.Core/Troubleshooting/TroubleshootingPlaybackStatusStore.cs new file mode 100644 index 000000000..da7fa5400 --- /dev/null +++ b/ErsatzTV.Core/Troubleshooting/TroubleshootingPlaybackStatusStore.cs @@ -0,0 +1,36 @@ +using ErsatzTV.Core.Interfaces.Troubleshooting; + +namespace ErsatzTV.Core.Troubleshooting; + +public class TroubleshootingPlaybackStatusStore : ITroubleshootingPlaybackStatusStore +{ + private readonly object _sync = new(); + private Option _result = Option.None; + + public Option CurrentResult + { + get + { + lock (_sync) + { + return _result; + } + } + } + + public void Reset() + { + lock (_sync) + { + _result = Option.None; + } + } + + public void RecordCompletion(int exitCode, Option speed) + { + lock (_sync) + { + _result = new TroubleshootingPlaybackResult(exitCode, speed); + } + } +} diff --git a/ErsatzTV/Startup.cs b/ErsatzTV/Startup.cs index 7b5ed4fe4..8edf58221 100644 --- a/ErsatzTV/Startup.cs +++ b/ErsatzTV/Startup.cs @@ -832,6 +832,7 @@ public class Startup services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(Program.InMemoryLogService);