From 3b229eab28814231a6da310f02ce9e84c45e7fb5 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Nov 2025 10:07:40 +0000 Subject: [PATCH] Correction du deadlock dans add_with_metadata (pmocache/src/db.rs) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problème identifié Le test test_add_with_metadata était bloqué indéfiniment à cause d'un deadlock. ## Cause Dans `add_with_metadata()`: 1. Ligne 195: Obtention du mutex sur la connexion DB 2. Ligne 208: Appel à `set_metadata()` qui essaie d'obtenir le MÊME mutex 3. Résultat: Deadlock permanent ## Solution - Encapsulation du premier bloc dans un scope pour libérer le lock automatiquement - Appel à `set_metadata()` après la libération du lock - Amélioration du code avec `if let Some(metadata)` au lieu de `if metadata.is_some()` ## Résultats - ✅ test_add_with_metadata passe maintenant en 0.07s (vs bloqué indéfiniment) - ✅ Tous les 16 tests DB passent en 0.29s - ✅ Test réactivé (retrait du #[ignore]) Cette correction est critique car elle affecte toute utilisation de `add_with_metadata()`. --- pmocache/src/db.rs | 28 ++++++++++++++++------------ pmocache/tests/test_db.rs | 1 - 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/pmocache/src/db.rs b/pmocache/src/db.rs index e73ca2a5..cf00bf77 100644 --- a/pmocache/src/db.rs +++ b/pmocache/src/db.rs @@ -192,20 +192,24 @@ impl DB { collection: Option<&str>, metadata: Option<&Value>, ) -> rusqlite::Result<()> { - let conn = self.lock_conn("add_with_metadata"); + // Bloc pour limiter la durée du lock + { + let conn = self.lock_conn("add_with_metadata"); - conn.execute( - "INSERT INTO asset (pk, id, collection, hits, last_used) - VALUES (?1, ?2, ?3, 0, ?4) - ON CONFLICT(pk) DO UPDATE SET - id = excluded.id, - collection = excluded.collection, - last_used = excluded.last_used", - params![pk, id, collection, Utc::now().to_rfc3339()], - )?; + conn.execute( + "INSERT INTO asset (pk, id, collection, hits, last_used) + VALUES (?1, ?2, ?3, 0, ?4) + ON CONFLICT(pk) DO UPDATE SET + id = excluded.id, + collection = excluded.collection, + last_used = excluded.last_used", + params![pk, id, collection, Utc::now().to_rfc3339()], + )?; + } // Lock libéré ici - if metadata.is_some() { - self.set_metadata(pk, metadata.unwrap())? + // Appeler set_metadata après avoir libéré le lock pour éviter un deadlock + if let Some(metadata) = metadata { + self.set_metadata(pk, metadata)?; } Ok(()) diff --git a/pmocache/tests/test_db.rs b/pmocache/tests/test_db.rs index c4b4a046..1066e7a2 100644 --- a/pmocache/tests/test_db.rs +++ b/pmocache/tests/test_db.rs @@ -43,7 +43,6 @@ fn test_add_and_get() { } #[test] -#[ignore] // Test trop lent, à investiguer fn test_add_with_metadata() { let (_temp_dir, db) = create_test_db();