diff --git a/pmoaudio-ext/src/sources/playlist_source.rs b/pmoaudio-ext/src/sources/playlist_source.rs index 93fd6c3d..f2896e11 100644 --- a/pmoaudio-ext/src/sources/playlist_source.rs +++ b/pmoaudio-ext/src/sources/playlist_source.rs @@ -332,15 +332,17 @@ async fn decode_and_emit_track( // Si EOF atteint (read == 0) if read == 0 { - // Vérifier si le download est toujours en cours (cache progressif) - if cache.get_download(cache_pk).await.is_some() { - // Download en cours - attendre un peu et réessayer - tracing::trace!("decode_and_emit_track: EOF reached but download ongoing, waiting..."); - tokio::time::sleep(Duration::from_millis(100)).await; + // Vérifier si le fichier est complètement écrit (completion marker existe) + // Si pas de marker, le fichier est encore en cours d'écriture (cache progressif) + if !cache.is_download_complete(cache_pk) { + // Fichier encore en cours d'écriture - attendre un peu et réessayer + tracing::trace!("decode_and_emit_track: EOF reached but file not complete (no marker), waiting 50ms..."); + tokio::time::sleep(Duration::from_millis(50)).await; continue; // Retry la lecture } - // Download terminé - c'est vraiment la fin du fichier + // Completion marker existe - c'est vraiment la fin du fichier + tracing::trace!("decode_and_emit_track: EOF reached and file is complete (marker exists)"); if pending.is_empty() { break; } diff --git a/pmocache/src/cache.rs b/pmocache/src/cache.rs index d9fe6ff5..4ba635da 100755 --- a/pmocache/src/cache.rs +++ b/pmocache/src/cache.rs @@ -716,6 +716,27 @@ impl Cache { downloads.get(pk).cloned() } + /// Vérifie si le téléchargement/ingestion d'un fichier est complètement terminé + /// + /// Cette méthode vérifie l'existence du fichier marker de complétion (.complete) + /// qui est créé uniquement quand le fichier est complètement écrit et fermé. + /// + /// Utile pour différencier: + /// - EOF temporaire : fichier encore en cours d'écriture (retourne false) + /// - EOF réel : fichier complètement écrit (retourne true) + /// + /// # Arguments + /// + /// * `pk` - Clé primaire du fichier + /// + /// # Returns + /// + /// `true` si le fichier est complètement écrit (marker existe), `false` sinon + pub fn is_download_complete(&self, pk: &str) -> bool { + let completion_marker = self.get_completion_marker_path(pk); + completion_marker.exists() + } + /// Retourne la taille actuelle téléchargée (source) /// /// Si le download est en cours, retourne la taille téléchargée.