Fix FlacCacheSink to not consume TrackBoundary when cache hit

Previous fix consumed the TrackBoundary with drain_until_track_boundary(),
preventing the next track from being processed correctly. This caused
audio to stop after the first cached track.

Solution: Use a pump_closed flag instead of draining. When the pump
closes early (cache hit), set the flag and ignore subsequent chunks
until TrackBoundary. The TrackBoundary is then handled normally by
the existing code, allowing proper continuation to the next track.

This preserves the block structure and allows all tracks in a block
to be processed correctly, whether cached or not.
This commit is contained in:
Claude
2025-11-07 16:16:09 +00:00
parent 483ec26dfe
commit 413047cce5

View File

@@ -299,6 +299,7 @@ impl NodeLogic for FlacCacheSinkLogic {
// Phase 3: Continuer à dispatcher jusqu'au TrackBoundary
tracing::debug!("FlacCacheSink: Continuing dispatch until TrackBoundary (pump runs in background)");
let mut pump_closed = false;
loop {
let segment = tokio::select! {
result = rx.recv() => {
@@ -306,22 +307,27 @@ impl NodeLogic for FlacCacheSinkLogic {
Some(seg) => seg,
None => {
// EOF sur rx
if !pump_closed {
drop(track_tx);
drop(pump_handle);
}
return Ok(());
}
}
}
_ = stop_token.cancelled() => {
if !pump_closed {
drop(track_tx);
drop(pump_handle);
}
return Ok(());
}
};
match &segment.segment {
_AudioSegment::Chunk(_) => {
// Continuer à dispatcher vers le pump
// Continuer à dispatcher vers le pump (sauf si déjà fermé)
if !pump_closed {
if track_tx.send(segment).await.is_err() {
// Le pump a fermé son channel - cela peut arriver si le fichier
// était déjà en cache (add_from_reader retourne immédiatement)
@@ -332,17 +338,8 @@ impl NodeLogic for FlacCacheSinkLogic {
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(());
}
}
tracing::debug!("FlacCacheSink: pump completed successfully, ignoring remaining chunks until TrackBoundary");
pump_closed = true;
}
Ok(Err(e)) => {
// Le pump a rencontré une erreur
@@ -357,25 +354,33 @@ impl NodeLogic for FlacCacheSinkLogic {
}
}
}
// Si pump_closed, ignorer silencieusement le chunk
}
_AudioSegment::Sync(marker) => match &**marker {
SyncMarker::TrackBoundary { .. } => {
// Nouveau morceau - fermer le pump et passer au suivant
// Nouveau morceau - fermer le pump si pas déjà fermé
tracing::debug!("FlacCacheSink: TrackBoundary received, closing pump");
if !pump_closed {
drop(track_tx); // Ferme le channel, le pump se termine proprement
drop(pump_handle);
}
track_number += 1;
break; // Sort de la Phase 3, retour à la loop externe pour next track
}
SyncMarker::EndOfStream => {
tracing::debug!("FlacCacheSink: EndOfStream received");
if !pump_closed {
drop(track_tx);
drop(pump_handle);
}
return Ok(());
}
_ => {
// Transmettre les autres syncmarkers au pump
// Transmettre les autres syncmarkers au pump (sauf si fermé)
if !pump_closed {
let _ = track_tx.send(segment).await;
}
}
},
}
}