From 28e33dc26f1f8ae3209cb4d5cd2dc2b2d1b5ec40 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Nov 2025 06:01:51 +0000 Subject: [PATCH] fix: Properly await async metadata setters in song_to_metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: - Used `let _ = metadata.set_title(...)` which creates unawaited Future - Futures were never executed → metadata fields never set! - Ignored Result<(), MetadataError> which could contain errors Solution: - Spawn tokio task to configure metadata asynchronously - Properly await all set_*() calls - Handle errors with eprintln! warnings instead of silent ignore - Clone all data upfront for the async task Type info: - metadata: MemoryTrackMetadata (concrete type) - Returns: Arc> (trait object) - Methods: async fn set_*(&mut self) -> MetadataResult<()> All 7 tests still pass ✅ --- .../src/radio_paradise_stream_source.rs | 62 ++++++++++++------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/pmoparadise/src/radio_paradise_stream_source.rs b/pmoparadise/src/radio_paradise_stream_source.rs index 9fb1e7d7..60805130 100644 --- a/pmoparadise/src/radio_paradise_stream_source.rs +++ b/pmoparadise/src/radio_paradise_stream_source.rs @@ -284,36 +284,50 @@ fn pcm_to_audio_segment( } /// Convertit Song en TrackMetadata +/// +/// Cette fonction est synchrone, donc on wrap la metadata dans Arc> +/// et on spawn une tâche async pour la configurer fn song_to_metadata(song: &Song, block: &Block) -> Arc> { - let mut metadata = MemoryTrackMetadata::new(); + let metadata = MemoryTrackMetadata::new(); + let metadata_arc = Arc::new(RwLock::new(metadata)) as Arc>; + let metadata_clone = metadata_arc.clone(); - let _ = metadata.set_title(Some(song.title.clone())); - let _ = metadata.set_artist(Some(song.artist.clone())); + // Clone des données pour la task async + let title = song.title.clone(); + let artist = song.artist.clone(); + let album = song.album.clone(); + let year = song.year; + let cover_url = song.cover.as_ref().and_then(|cover| block.cover_url(cover)); - if let Some(ref album) = song.album { - let _ = metadata.set_album(Some(album.clone())); - } + // Configurer les métadonnées de manière asynchrone + tokio::spawn(async move { + let mut meta = metadata_clone.write().await; - if let Some(year) = song.year { - let _ = metadata.set_year(Some(year)); - } - - // Cover URL si disponible - if let Some(ref cover_path) = song.cover { - if let Some(cover_url) = block.cover_url(cover_path) { - let metadata_arc = Arc::new(RwLock::new(metadata)) as Arc>; - let metadata_clone = metadata_arc.clone(); - - tokio::spawn(async move { - let mut meta = metadata_clone.write().await; - let _ = meta.set_cover_url(Some(cover_url)).await; - }); - - return metadata_arc; + // Ces méthodes peuvent échouer (retournent Result), donc on propage avec ? + if let Err(e) = meta.set_title(Some(title)).await { + eprintln!("Warning: Failed to set title: {}", e); } - } + if let Err(e) = meta.set_artist(Some(artist)).await { + eprintln!("Warning: Failed to set artist: {}", e); + } + if let Some(album) = album { + if let Err(e) = meta.set_album(Some(album)).await { + eprintln!("Warning: Failed to set album: {}", e); + } + } + if let Some(year) = year { + if let Err(e) = meta.set_year(Some(year)).await { + eprintln!("Warning: Failed to set year: {}", e); + } + } + if let Some(cover_url) = cover_url { + if let Err(e) = meta.set_cover_url(Some(cover_url)).await { + eprintln!("Warning: Failed to set cover_url: {}", e); + } + } + }); - Arc::new(RwLock::new(metadata)) + metadata_arc } #[async_trait::async_trait]