Add [BP-DIAG] back-pressure instrumentation for Phase 21.4 browser run
Temporary, grep-tagged diagnostics at the read-loop pause, the scheduler latch, and the chunk-result path to show whether ProductionPaused latches, reaches C#, and parks the loop. Strip once the cause is confirmed.
This commit is contained in:
@@ -35,6 +35,14 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS
|
||||
public int BufferedChunks { get; private set; } = 0;
|
||||
public bool IsSeekingBeyondBuffer { get; private set; } = false;
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────────────────────────────
|
||||
// [BP-DIAG] Phase 21.4 back-pressure diagnostic. TEMPORARY — strip once the cause is confirmed
|
||||
// in Daniel's browser run. Logs every Nth chunk's ProductionPaused flag plus pause-poll
|
||||
// enter/exit so a grep for "[BP-DIAG]" in the WASM console tells whether the read loop ever sees
|
||||
// the pause signal and whether the poll actually holds. Throttled by chunk count to avoid flooding.
|
||||
private const int BpDiagChunkLogEvery = 16;
|
||||
// ───────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
private bool _streamingPlaybackStarted = false;
|
||||
private CancellationTokenSource? _streamingCancellation;
|
||||
private Task? _activeStreamingTask;
|
||||
@@ -386,6 +394,7 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS
|
||||
buffer = ArrayPool<byte>.Shared.Rent(MaxBufferSize); // Rent larger buffer to accommodate adaptive sizing
|
||||
int currentBytes;
|
||||
var readTimer = System.Diagnostics.Stopwatch.StartNew();
|
||||
var bpDiagChunkIndex = 0; // [BP-DIAG] per-stream chunk counter for throttled logging
|
||||
|
||||
do
|
||||
{
|
||||
@@ -420,6 +429,20 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS
|
||||
HeaderParsed = chunkResult.HeaderParsed;
|
||||
BufferedChunks = chunkResult.BufferCount;
|
||||
|
||||
// [BP-DIAG] Phase 21.4 — throttled per-chunk view of the back-pressure signal as
|
||||
// the C# loop sees it. If ProductionPaused never logs True while bytes keep
|
||||
// flowing, the break is upstream (JS latch / lookahead math); if it logs True but
|
||||
// the transfer still races to 100%, the break is the transport (browser buffered
|
||||
// the whole body, SetBrowserResponseStreamingEnabled not in effect). TEMPORARY.
|
||||
if (bpDiagChunkIndex % BpDiagChunkLogEvery == 0)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"[BP-DIAG] chunk #{Chunk} bytesRead={Bytes} totalRead={Total} bufferCount={BufCount} canStart={CanStart} productionPaused={Paused} isPaused={IsPaused}",
|
||||
bpDiagChunkIndex, currentBytes, totalBytesRead, chunkResult.BufferCount,
|
||||
chunkResult.CanStartStreaming, chunkResult.ProductionPaused, IsPaused);
|
||||
}
|
||||
bpDiagChunkIndex++;
|
||||
|
||||
// Set duration from WAV header when available (only set once)
|
||||
if (chunkResult.Duration.HasValue && Duration == null)
|
||||
{
|
||||
@@ -487,6 +510,15 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS
|
||||
// no separate cancellation path, no stale read racing a reinit.
|
||||
if (chunkResult.ProductionPaused)
|
||||
{
|
||||
// [BP-DIAG] Phase 21.4 — the read loop is ENTERING the pause-poll: reads have
|
||||
// stopped, the socket should now stall and the transfer should plateau. If you
|
||||
// see this line but the network transfer still completes, the transport is
|
||||
// buffered (streaming flag not in effect). TEMPORARY.
|
||||
_logger.LogInformation(
|
||||
"[BP-DIAG] ENTER pause-poll at chunk #{Chunk} totalRead={Total} isPaused={IsPaused}",
|
||||
bpDiagChunkIndex, totalBytesRead, IsPaused);
|
||||
var bpDiagPollCount = 0;
|
||||
|
||||
// UC5: while the user is paused, the playhead is frozen so forward lookahead
|
||||
// never shrinks and the poll would spin indefinitely. Wait here until playback
|
||||
// resumes (IsPaused clears) OR the fill drains on its own. Cancellation is
|
||||
@@ -495,8 +527,23 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS
|
||||
while (IsPaused || await _audioInterop.IsProductionPaused(PlayerId))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
// [BP-DIAG] Phase 21.4 — heartbeat every ~1 s (10 × 100 ms) so a held poll
|
||||
// is visible without flooding; shows the loop is genuinely parked. TEMPORARY.
|
||||
if (bpDiagPollCount % 10 == 0)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"[BP-DIAG] HOLD pause-poll iter={Iter} isPaused={IsPaused}",
|
||||
bpDiagPollCount, IsPaused);
|
||||
}
|
||||
bpDiagPollCount++;
|
||||
await Task.Delay(BackpressurePollMs, cancellationToken);
|
||||
}
|
||||
|
||||
// [BP-DIAG] Phase 21.4 — the read loop is EXITING the pause-poll and resuming
|
||||
// ReadAsync: the fill drained below low-water. TEMPORARY.
|
||||
_logger.LogInformation(
|
||||
"[BP-DIAG] EXIT pause-poll at chunk #{Chunk} after {Iters} polls",
|
||||
bpDiagChunkIndex, bpDiagPollCount);
|
||||
}
|
||||
}
|
||||
} while (currentBytes > 0);
|
||||
|
||||
Reference in New Issue
Block a user