mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 06:25:41 +00:00
diag(audio): trace ranged-stream supersedion + abort paths
Skipping tracks while a RangedHttpSource is still in initial probe leaves no diagnostic trail today: RangedHttpSource::read returns Ok(0) on gen-mismatch (silent), ranged_download_task drops out the same way, and the `dl done` summary only fires under app_deprintln so release users never see partial/aborted downloads either. Add focused logs at the bail points without changing behaviour: - RangedHttpSource::read — log on each Ok(0) return that isn't the normal pos>=total_size EOF (superseded before/during wait, download done with no bytes ahead of cursor). Symphonia stops reading after Ok(0), so at most one log per source, no spam. - ranged_download_task — log on the gen-mismatch bail with track id + gen transition + downloaded/total bytes so we can tell "user skipped while downloading" apart from "stream stalled". - track_download_task — same gen-mismatch log for the legacy non-seekable path (consistency with ranged). - dl-done summary — split into release-visible `[stream] ranged dl ABORTED: …` (downloaded < total_size) vs the existing dev-only `[stream] dl done` for full completions. - audio_play — log on both supersedion-bail points around select_play_input so a silently-ending audio_play call leaves a trace. No semantics changed: every existing return / store / branch is intact. Pure additive logging to make the next reproduction of cucadmuh's ranged-stream toast diagnosable.
This commit is contained in:
@@ -147,11 +147,21 @@ pub async fn audio_play(
|
||||
&app,
|
||||
).await? {
|
||||
Some(input) => input,
|
||||
None => return Ok(()), // superseded — bail
|
||||
None => {
|
||||
crate::app_deprintln!(
|
||||
"[audio] audio_play superseded inside select_play_input: gen={} cur={} track_id={:?}",
|
||||
gen, state.generation.load(Ordering::SeqCst), cache_id_for_tasks
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if state.generation.load(Ordering::SeqCst) != gen {
|
||||
crate::app_deprintln!(
|
||||
"[audio] audio_play superseded after select_play_input: gen={} cur={} track_id={:?}",
|
||||
gen, state.generation.load(Ordering::SeqCst), cache_id_for_tasks
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,10 @@ pub(crate) struct RangedHttpSource {
|
||||
impl Read for RangedHttpSource {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
if self.gen_arc.load(Ordering::SeqCst) != self.gen {
|
||||
crate::app_deprintln!(
|
||||
"[stream] ranged-stream read EOF: superseded before first read (gen={} cur={} pos={}/{})",
|
||||
self.gen, self.gen_arc.load(Ordering::SeqCst), self.pos, self.total_size
|
||||
);
|
||||
return Ok(0);
|
||||
}
|
||||
if self.pos >= self.total_size {
|
||||
@@ -303,6 +307,11 @@ impl Read for RangedHttpSource {
|
||||
let deadline = Instant::now() + Duration::from_secs(RADIO_READ_TIMEOUT_SECS);
|
||||
loop {
|
||||
if self.gen_arc.load(Ordering::SeqCst) != self.gen {
|
||||
crate::app_deprintln!(
|
||||
"[stream] ranged-stream read EOF: superseded mid-wait (gen={} cur={} pos={}/{} dl={})",
|
||||
self.gen, self.gen_arc.load(Ordering::SeqCst), self.pos, self.total_size,
|
||||
self.downloaded_to.load(Ordering::SeqCst)
|
||||
);
|
||||
return Ok(0);
|
||||
}
|
||||
let dl = self.downloaded_to.load(Ordering::SeqCst) as u64;
|
||||
@@ -321,6 +330,10 @@ impl Read for RangedHttpSource {
|
||||
self.pos += avail as u64;
|
||||
return Ok(avail);
|
||||
}
|
||||
crate::app_deprintln!(
|
||||
"[stream] ranged-stream read EOF: download done with no data ahead of cursor (pos={}/{} dl={})",
|
||||
self.pos, self.total_size, dl
|
||||
);
|
||||
return Ok(0);
|
||||
}
|
||||
if Instant::now() >= deadline {
|
||||
@@ -654,6 +667,10 @@ pub(crate) async fn track_download_task(
|
||||
let mut byte_stream = response.bytes_stream();
|
||||
while let Some(chunk) = byte_stream.next().await {
|
||||
if gen_arc.load(Ordering::SeqCst) != gen {
|
||||
crate::app_deprintln!(
|
||||
"[stream] track-stream dl superseded by skip: track_id={:?} gen={}→{}",
|
||||
cache_track_id, gen, gen_arc.load(Ordering::SeqCst)
|
||||
);
|
||||
done.store(true, Ordering::SeqCst);
|
||||
return;
|
||||
}
|
||||
@@ -842,6 +859,10 @@ pub(crate) async fn ranged_download_task(
|
||||
let mut byte_stream = response.bytes_stream();
|
||||
while let Some(chunk) = byte_stream.next().await {
|
||||
if gen_arc.load(Ordering::SeqCst) != gen {
|
||||
crate::app_deprintln!(
|
||||
"[stream] ranged dl superseded by skip: track_id={:?} gen={}→{} downloaded={}/{} bytes",
|
||||
cache_track_id, gen, gen_arc.load(Ordering::SeqCst), downloaded, total_size
|
||||
);
|
||||
done.store(true, Ordering::SeqCst);
|
||||
return;
|
||||
}
|
||||
@@ -928,13 +949,24 @@ pub(crate) async fn ranged_download_task(
|
||||
|
||||
done.store(true, Ordering::SeqCst);
|
||||
|
||||
crate::app_deprintln!(
|
||||
"[stream] dl done: {} / {} bytes in {:.2}s ({} reconnects)",
|
||||
downloaded,
|
||||
total_size,
|
||||
dl_started.elapsed().as_secs_f64(),
|
||||
reconnects
|
||||
);
|
||||
if downloaded < total_size {
|
||||
crate::app_eprintln!(
|
||||
"[stream] ranged dl ABORTED: {} / {} bytes in {:.2}s ({} reconnects, track_id={:?})",
|
||||
downloaded,
|
||||
total_size,
|
||||
dl_started.elapsed().as_secs_f64(),
|
||||
reconnects,
|
||||
cache_track_id
|
||||
);
|
||||
} else {
|
||||
crate::app_deprintln!(
|
||||
"[stream] dl done: {} / {} bytes in {:.2}s ({} reconnects)",
|
||||
downloaded,
|
||||
total_size,
|
||||
dl_started.elapsed().as_secs_f64(),
|
||||
reconnects
|
||||
);
|
||||
}
|
||||
|
||||
if downloaded == total_size && total_size > 0 && total_size <= TRACK_STREAM_PROMOTE_MAX_BYTES {
|
||||
if let Some(ref tid) = cache_track_id {
|
||||
|
||||
Reference in New Issue
Block a user