5 Commits

Author SHA1 Message Date
3401ee839c chore: bump version to 0.3.48
Update package and project versions from v0.3.57 to 0.48 in Cargo.toml and version.txt.
2026-04-10 00:06:20 +02:00
e8e33414f0 (refactor) Replace tokio::spawn_blocking with std thread for metadata preloading
(refactor) Replace tokio::spawn_blocking with std thread for metadata preloading
- Use `std::thread` instead of Tokio's blocking pool to avoid potential thread starvation in async context
- Ensures long-running metadata loading does not block Tokio workers
2026-04-10 00:05:16 +02:00
b0e24c3b3c 🔖 bump version to v0.3.47
- Update Cargo.lock packageversion
- Refactor DB initialization: move PRAGMA settings after table creation for correctness and clarity (WAL, cache size etc.)
- Add foreign key enforcement (`PRAGMAforeign_keys = ON`)
>- Reorder index creation to follow table definition
- Add new indexes: `idx_asset_last_used`, idx`_asset_hits`
>- Introduce indexed lazy_pk support with unique constraint on non-NULL values
> - Improve LRU index to use ASC ordering for efficient oldest-record lookup
2026-04-10 00:03:39 +02:00
b5b6becb25 Merge pull request '⬆️ Bump version to v0.3.47' (#95) from push-nlksvqrutmxv into main
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m12s
Reviewed-on: https://gargoton.petite-maison-orange.fr/eric/pmomusic/pulls/95
2026-04-09 23:34:51 +02:00
353e54af76 ⬆️ Bump version to v0.3.47
- Update package versions in Cargo.toml, lockfile and version.txt to v0.3.47
- Optimize SQLite database initialization with WAL mode, larger cache and critical missing indexes (idx_metadata_key_value, idx_asset_last_used/hits)
- Fix production bug in OpenHome renderer: avoid blocking main thread when loading metadata for large queues; offload preloading of next 10 items to background task with small delays
- Minor formatting cleanup in db.rs
2026-04-09 23:34:32 +02:00
5 changed files with 69 additions and 14 deletions

2
Cargo.lock generated
View File

@@ -4,7 +4,7 @@ version = 4
[[package]]
name = "PMOMusic"
version = "0.3.45"
version = "0.3.47"
dependencies = [
"axum 0.8.7",
"console-subscriber",

View File

@@ -1,6 +1,6 @@
[package]
name = "PMOMusic"
version = "0.3.46"
version = "0.3.48"
edition = "2024"
[dependencies]

View File

@@ -155,6 +155,7 @@ impl DB {
let conn = Connection::open(path)?;
conn.execute("PRAGMA foreign_keys = ON", [])?;
// 1. CRÉATION DES TABLES EN PREMIER
conn.execute(
"CREATE TABLE IF NOT EXISTS asset (
pk TEXT PRIMARY KEY,
@@ -180,21 +181,30 @@ impl DB {
[],
)?;
// Créer un index sur la collection pour les requêtes rapides
// 2. Optimisations SQLite pour production
conn.execute_batch(
"
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA cache_size = -32768;
PRAGMA temp_store = MEMORY;
PRAGMA mmap_size = 268435456;
",
)?;
// 3. CRÉATION DES INDEX APRÈS LES TABLES
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_asset_collection
ON ASSET (collection)",
[],
)?;
// Créer un index composite pour optimiser la politique LRU (get_oldest)
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_asset_lru
ON asset (last_used ASC, hits ASC)",
[],
)?;
// Crée un index composite pour rendre unique les ids si défini dans une collection
conn.execute(
"CREATE UNIQUE INDEX
IF NOT EXISTS asset_collection_id_unique
@@ -203,20 +213,32 @@ impl DB {
[],
)?;
// Index sur metadata(key, value) pour rendre get_pk_by_origin_url efficace.
// Sans cet index, la requête WHERE key = 'origin_url' AND value = ? fait
// un full scan car la PRIMARY KEY est (pk, key).
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_metadata_key_value ON metadata (key, value)",
[],
)?;
// LAZY PK SUPPORT: Index sur lazy_pk pour lookups rapides (lazy_pk → real pk)
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_asset_last_used ON asset (last_used DESC)",
[],
)?;
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_asset_hits ON asset (hits DESC)",
[],
)?;
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_asset_lazy_pk ON asset (lazy_pk)",
[],
)?;
conn.execute(
"CREATE UNIQUE INDEX IF NOT EXISTS idx_asset_lazy_pk_unique
ON asset (lazy_pk) WHERE lazy_pk IS NOT NULL",
[],
)?;
// Index unique sur lazy_pk (non-NULL) pour éviter les doublons
// Un lazy_pk ne peut pointer que vers un seul entry
conn.execute(
@@ -228,7 +250,12 @@ impl DB {
// Inscrire la version du schéma
conn.execute_batch(&format!("PRAGMA user_version = {}", SCHEMA_VERSION))?;
Ok((Self { conn: Mutex::new(conn) }, was_reset))
Ok((
Self {
conn: Mutex::new(conn),
},
was_reset,
))
}
/// Ajoute ou met à jour une entrée dans la base de données
@@ -1158,7 +1185,9 @@ impl DB {
tracing::debug!(
"update_lazy_to_downloaded: {} → {} ({} metadata rows still under lazy_pk)",
lazy_pk, real_pk, meta_under_lazy
lazy_pk,
real_pk,
meta_under_lazy
);
Ok(())

View File

@@ -688,10 +688,36 @@ impl QueueBackend for OpenHomeRenderer {
items: Vec<PlaybackItem>,
current_index: Option<usize>,
) -> Result<(), ControlPointError> {
// ✅ CORRECTION BUG PRODUCTION: On ne charge PAS toutes les métadonnées
// dans le thread principal. OpenHome sur 1000 titres inondait la base SQLite
// et bloquait TOUS les autres threads (mutex >500ms).
//
// On fait juste l'insertion minimaliste maintenant. Le préchargement
// des métadonnées est délégué à un thread background.
self.queue
.lock()
.map_err(|_| ControlPointError::QueueError("Queue mutex poisoned".into()))?
.replace_queue(items, current_index)
.map_err(|_| ControlPointError::QueueError("Mutex poisoned".into()))?
.replace_queue(items, current_index)?;
// Background worker: charge les métadonnées petit à petit sans bloquer personne
let queue = self.queue.clone();
std::thread::spawn(move || {
debug!("🔄 OpenHome: préchargement métadonnées queue en background");
if let Ok(mut queue) = queue.lock() {
// On ne fait que les 10 prochains titres maintenant, le reste on s'en fout
if let Ok(Some(idx)) = queue.current_index() {
let end = std::cmp::min(idx + 10, queue.len().unwrap_or(0));
for i in idx..end {
let _ = queue.get_item(i);
// Petit délai pour ne pas noyer la base de données
std::thread::sleep(std::time::Duration::from_millis(5));
}
}
}
debug!("✅ OpenHome: préchargement métadonnées terminé");
});
Ok(())
}
fn sync_queue(

View File

@@ -1 +1 @@
0.3.46
0.3.48