Skip to content

decode_task_fn signals decode errors with None, so the DSP task emits TrackEnded for a track that never played #402

Description

@forkwright

Finding

On a decode-loop error (engine.rs:333-342) the decode task emits EngineEvent::Error and then calls frame_tx.send(None).await.ok(). The frame channel uses None to mean end-of-stream, so the DSP task cannot distinguish an error termination from a clean EOS: it unconditionally emits EngineEvent::TrackEnded { source } (engine.rs:403) followed by PlaybackStopped. Every track that fails to decode is reported as a completed track.

Evidence

crates/akouo-core/src/engine.rs:341

frame_tx.send(None).await.ok();

DSP task at crates/akouo-core/src/engine.rs:403:

event_tx.send(EngineEvent::TrackEnded { source: source.clone(), }).ok();

Why this matters

Callers that count TrackEnded to advance the play queue, increment play-count metrics, or mark tracks as listened will record a false completion for every decode failure. Concrete consequences are play-count inflation, premature queue advancement, and inaccurate recently-played history — state that diverges from what actually played.

Desired correction

Distinguish error termination from EOS in the frame channel — for example, reserve None for a clean EOS and signal errors by dropping the sender or sending a dedicated error variant — and have the DSP task emit TrackEnded only on a clean EOS. Done when: a decode error produces EngineEvent::Error and EngineEvent::PlaybackStopped but not EngineEvent::TrackEnded.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions