fix: preserve prepared workflow state

This commit is contained in:
2026-07-11 12:45:03 +09:00
parent d11abfa567
commit 8864440ac7
2 changed files with 112 additions and 11 deletions

View File

@@ -74,10 +74,12 @@ public sealed class LegacyPlayoutWorkflow
private readonly IPlayoutEngine _engine;
private readonly ILegacySceneCueProvider _cueProvider;
private readonly SemaphoreSlim _gate = new(1, 1);
private readonly object _engineStatusSync = new();
private IReadOnlyList<LegacyPlaylistEntry> _playlist = [];
private ActivePage? _prepared;
private ActivePage? _onAir;
private int _engineClearRequested;
private long _lastObservedEngineStatusSequence = long.MinValue;
public LegacyPlayoutWorkflow(
IPlayoutEngine engine,
@@ -98,13 +100,27 @@ public sealed class LegacyPlayoutWorkflow
public void ObserveEngineStatus(PlayoutStatus status)
{
ArgumentNullException.ThrowIfNull(status);
if (!string.IsNullOrWhiteSpace(status.PreparedSceneName) ||
!string.IsNullOrWhiteSpace(status.OnAirSceneName))
var hasActiveScene = !string.IsNullOrWhiteSpace(status.PreparedSceneName) ||
!string.IsNullOrWhiteSpace(status.OnAirSceneName);
lock (_engineStatusSync)
{
if (status.Sequence <= _lastObservedEngineStatusSequence)
{
return;
}
_lastObservedEngineStatusSequence = status.Sequence;
// Availability/OnHello updates can report no scene while PREPARE still owns
// the workflow gate. A later authoritative PREPARED/PROGRAM status must
// cancel that deferred clear before the command publishes its page metadata.
Interlocked.Exchange(ref _engineClearRequested, hasActiveScene ? 0 : 1);
}
if (hasActiveScene)
{
return;
}
Interlocked.Exchange(ref _engineClearRequested, 1);
if (!_gate.Wait(0))
{
return;
@@ -538,15 +554,18 @@ public sealed class LegacyPlayoutWorkflow
private void ApplyRequestedEngineClear()
{
if (Interlocked.Exchange(ref _engineClearRequested, 0) == 0)
lock (_engineStatusSync)
{
return;
}
if (Interlocked.Exchange(ref _engineClearRequested, 0) == 0)
{
return;
}
_prepared = null;
_onAir = null;
_playlist = [];
State = EmptyState;
_prepared = null;
_onAir = null;
_playlist = [];
State = EmptyState;
}
}
private static readonly LegacyPlayoutWorkflowState EmptyState = new(