Fix FlacCacheSink error when reusing cached files

When a file was already in cache, add_from_reader() would return
immediately after reading only 1024 bytes to compute the pk. This
closed the flac_stream and pcm_tx, causing the pump to terminate
normally. However, the dispatcher treated track_tx.send() failure
as a fatal error, even though the pump had completed successfully.

Changes:
- In phase 3 post-prebuffer, when track_tx.send() fails, wait for
  pump to complete and check its result
- If pump returned Ok(), drain remaining segments until TrackBoundary
- If pump returned Err(), propagate the error
- This allows graceful handling of cache hits while preserving error
  detection for genuine pump failures

Fixes the "Pump task died" error when relaunching play_and_cache
with existing cached files.
This commit is contained in:
Claude
2025-11-07 16:05:29 +00:00
parent 03bc9c9ae7
commit 483ec26dfe

View File

@@ -323,9 +323,38 @@ impl NodeLogic for FlacCacheSinkLogic {
_AudioSegment::Chunk(_) => {
// Continuer à dispatcher vers le pump
if track_tx.send(segment).await.is_err() {
// Le pump est mort - erreur
tracing::error!("FlacCacheSink: pump died during post-prebuffer phase");
return Err(AudioError::ProcessingError("Pump task died".to_string()));
// Le pump a fermé son channel - cela peut arriver si le fichier
// était déjà en cache (add_from_reader retourne immédiatement)
tracing::debug!("FlacCacheSink: pump closed track_tx, checking pump status");
drop(track_tx);
// Attendre que le pump se termine et vérifier le résultat
match pump_handle.await {
Ok(Ok(_)) => {
// Le pump s'est terminé proprement (fichier était en cache)
tracing::debug!("FlacCacheSink: pump completed successfully, draining remaining segments");
// Drainer les segments restants jusqu'au TrackBoundary
match drain_until_track_boundary(&mut rx, &stop_token).await? {
StopReason::TrackBoundary(_) => {
track_number += 1;
break; // Continue avec la prochaine track
}
StopReason::EndOfStream | StopReason::ChannelClosed => {
return Ok(());
}
}
}
Ok(Err(e)) => {
// Le pump a rencontré une erreur
tracing::error!("FlacCacheSink: pump died with error: {}", e);
return Err(e);
}
Err(e) => {
// Le pump task a paniqué
tracing::error!("FlacCacheSink: pump task panicked: {}", e);
return Err(AudioError::ProcessingError("Pump task panicked".to_string()));
}
}
}
}
_AudioSegment::Sync(marker) => match &**marker {