From 483ec26dfe251e4fdf8180977f37d70be23f37c2 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Nov 2025 16:05:29 +0000 Subject: [PATCH] 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. --- pmoaudio-ext/src/sinks/flac_cache_sink.rs | 35 +++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/pmoaudio-ext/src/sinks/flac_cache_sink.rs b/pmoaudio-ext/src/sinks/flac_cache_sink.rs index d0a0d359..0bbb38da 100755 --- a/pmoaudio-ext/src/sinks/flac_cache_sink.rs +++ b/pmoaudio-ext/src/sinks/flac_cache_sink.rs @@ -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 {