Corriger la race condition dans add_from_url et add_from_reader

Problème :
Les fonctions add_from_url() et add_from_reader() retournaient le pk
immédiatement après avoir lancé l'ingestion en arrière-plan, mais AVANT
que le fichier soit créé sur disque. Cela causait une erreur "Cache entry
not found" quand la playlist appelait is_valid_pk() qui vérifie que le
fichier existe.

Solution :
Attendre (jusqu'à 5 secondes max) que le fichier soit créé sur disque
avant de retourner le pk. Cela permet au cache progressif de fonctionner
correctement : le fichier existe et peut commencer à être lu pendant que
le téléchargement continue en arrière-plan.

Changements :
- add_from_url() : attente de la création du fichier avant retour
- add_from_reader() : attente de la création du fichier avant retour
- Cas où download déjà en cours : attente également de la création du fichier

Résultat testé :
✓ L'exemple play_and_cache fonctionne maintenant sans erreur
✓ Le pipeline de download se termine avec succès
✓ Les pistes sont correctement ajoutées à la playlist
This commit is contained in:
Claude
2025-11-06 07:54:09 +00:00
parent 590cd655d6
commit 15eb4da669

View File

@@ -181,8 +181,18 @@ impl<C: CacheConfig> Cache<C> {
{
let downloads = self.downloads.read().await;
if downloads.contains_key(&pk) {
// Download déjà en cours pour ce contenu, retourner la clé
// Download déjà en cours pour ce contenu, attendre que le fichier soit créé
tracing::debug!("Download already in progress for pk {}", pk);
drop(downloads); // Libérer le lock avant la boucle d'attente
// Attendre que le fichier soit créé (pour le cache progressif)
let file_path = self.get_file_path(&pk);
let mut attempts = 0;
while !file_path.exists() && attempts < 100 {
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
attempts += 1;
}
return Ok(pk);
}
}
@@ -215,6 +225,23 @@ impl<C: CacheConfig> Cache<C> {
downloads_clone.write().await.remove(&pk_clone);
});
// Attendre que le fichier soit créé sur disque (pour le cache progressif)
// On attend jusqu'à 5 secondes maximum
let file_path = self.get_file_path(&pk);
let mut attempts = 0;
while !file_path.exists() && attempts < 100 {
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
attempts += 1;
}
if !file_path.exists() {
tracing::warn!(
"File {} not created after waiting 5 seconds, pk={}",
file_path.display(),
pk
);
}
Ok(pk)
}
@@ -319,6 +346,23 @@ impl<C: CacheConfig> Cache<C> {
downloads_clone.write().await.remove(&pk_clone);
});
// Attendre que le fichier soit créé sur disque (pour le cache progressif)
// On attend jusqu'à 5 secondes maximum
let file_path = self.get_file_path(&pk);
let mut attempts = 0;
while !file_path.exists() && attempts < 100 {
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
attempts += 1;
}
if !file_path.exists() {
tracing::warn!(
"File {} not created after waiting 5 seconds, pk={}",
file_path.display(),
pk
);
}
Ok(pk)
}