Corrected polling regression causing 2-3 second jumps in OpenHome renderer progress bar - Fixed watcher loop timing to use fixed intervals instead of fixed pauses - Eliminated redundant SOAP calls to playback_position() by implementing intelligent caching - Restructured poll_and_emit_changes() to minimize lock contention - Reduced unnecessary network calls and improved performance This resolves the UI progress bar stuttering issue while maintaining correct playback state detection.
161 lines
5.9 KiB
Markdown
161 lines
5.9 KiB
Markdown
# Rapport : Correction de la régression du polling OpenHome
|
|
|
|
## Résumé
|
|
|
|
Suite au crash de Claude Code, investigation et correction d'une régression causant des sauts de 2-3 secondes dans la barre de progression de l'interface web pour les renderers OpenHome. Le problème provenait d'une combinaison de facteurs : timing incorrect de la boucle de polling et appels SOAP redondants.
|
|
|
|
## Fichiers modifiés
|
|
|
|
1. `pmocontrol/src/music_renderer/musicrenderer.rs`
|
|
- Correction du timing de la boucle watcher (intervalle fixe au lieu de pause fixe)
|
|
- Suppression d'un appel double à `playback_position()`
|
|
- Réorganisation de `poll_and_emit_changes()` pour minimiser le temps passé avec les locks
|
|
|
|
2. `pmocontrol/src/music_renderer/openhome_renderer.rs`
|
|
- Ajout d'un cache intelligent pour `playback_position()` avec timestamp et détection d'abus
|
|
- Évite les appels SOAP redondants (OpenHome a précision à la seconde)
|
|
|
|
3. `pmocontrol/src/music_renderer/watcher.rs`
|
|
- Modifications temporaires annulées (cache déplacé dans OpenHomeRenderer)
|
|
|
|
## Analyse des appels SOAP OpenHome - Services de LECTURE
|
|
|
|
Analyse effectuée sur le renderer OpenHome `pizzicato-Music` (192.168.0.200) à partir des logs `pmomusic.log`.
|
|
|
|
### Services analysés et intervalles observés
|
|
|
|
#### ✅ Time:Time (après correction)
|
|
- **Intervalle moyen** : ~1050ms
|
|
- **Min/Max** : 1000-1200ms
|
|
- **État** : CORRIGÉ - Cache actif, fonctionne parfaitement
|
|
- **Appels** : Réguliers, espacés d'environ 1 seconde
|
|
|
|
#### ⚠️ Playlist:TransportState
|
|
- **Intervalle moyen** : ~150ms
|
|
- **Distribution** :
|
|
- 100ms : 7 occurrences
|
|
- 200ms : 1 occurrence
|
|
- 700ms : 1 occurrence
|
|
- **État** : PROBLÉMATIQUE - Sur-sollicitation
|
|
- **Impact** : Appelé 6-7 fois par seconde au lieu de 2 fois
|
|
|
|
#### ⚠️ Playlist:IdArray
|
|
- **Intervalle moyen** : ~320ms (très irrégulier)
|
|
- **Distribution** :
|
|
- 0ms : 2 occurrences (!)
|
|
- 100ms : 3 occurrences
|
|
- 200ms : 1 occurrence
|
|
- 800-1000ms : 3 occurrences
|
|
- **État** : TRÈS PROBLÉMATIQUE - Appels anarchiques
|
|
- **Impact** : Certains appels consécutifs sans délai, surcharge réseau
|
|
|
|
#### ⚠️ Product:SourceXml
|
|
- **Intervalle moyen** : ~130ms
|
|
- **Distribution** :
|
|
- 100ms : 8 occurrences
|
|
- 200ms : 1 occurrence
|
|
- 300ms : 1 occurrence
|
|
- **État** : PROBLÉMATIQUE - Sur-sollicitation
|
|
- **Impact** : Appelé 7-8 fois par seconde au lieu de 2 fois
|
|
|
|
#### ⚠️ Product:SourceIndex
|
|
- **Données** : Observé dans les logs mais pas analysé en détail
|
|
- **État** : Probablement similaire à SourceXml
|
|
|
|
#### 📊 Volume:Volume & Volume:Mute
|
|
- **Données** : Insuffisantes dans les logs récents
|
|
- **Polling prévu** : Toutes les 2 ticks (1 seconde) selon le code
|
|
- **État** : À surveiller
|
|
|
|
### Services d'ÉCRITURE
|
|
|
|
Aucun appel récent observé dans les logs (comportement normal - ce sont des commandes utilisateur ponctuelles) :
|
|
- Playlist:Play
|
|
- Playlist:Pause
|
|
- Playlist:Stop
|
|
- Playlist:SeekId
|
|
- Playlist:SeekSecondAbsolute
|
|
- Volume:SetVolume
|
|
- Volume:SetMute
|
|
|
|
## Problèmes identifiés
|
|
|
|
### 1. Timing de la boucle watcher (CORRIGÉ)
|
|
**Avant** : `sleep(500ms)` APRÈS chaque poll
|
|
- Poll prend 100-200ms → Intervalle réel = 600-700ms
|
|
|
|
**Après** : Intervalle fixe de 500ms entre le DÉBUT de chaque poll
|
|
- Utilise `SystemTime` pour calculer le prochain poll
|
|
- Ajuste le sleep en conséquence
|
|
|
|
### 2. Lock contention (CORRIGÉ)
|
|
**Avant** : Lock `watched_state` tenu pendant les appels réseau
|
|
- Bloque autres threads pendant 50-200ms
|
|
- Cause des délais cumulatifs
|
|
|
|
**Après** : Locks acquis uniquement pour comparaison/mise à jour
|
|
- Appels réseau faits SANS locks
|
|
- Locks relâchés avant émission d'événements
|
|
|
|
### 3. Appels SOAP redondants OpenHome:Time (CORRIGÉ)
|
|
**Avant** : Aucun cache, appel SOAP à chaque poll (500ms)
|
|
- OpenHome retourne `elapsed_secs` (précision seconde)
|
|
- Appels inutiles car valeur identique
|
|
|
|
**Après** : Cache avec expiration 900ms + détection d'abus
|
|
- Retourne valeur cachée si < 900ms
|
|
- Warning si > 3 appels/seconde
|
|
- Réduit appels SOAP de moitié
|
|
|
|
### 4. Appel double à playback_position() (CORRIGÉ)
|
|
**Avant** : Deux appels dans `poll_and_emit_changes()`
|
|
```rust
|
|
let raw_position = self.lock_backend_for("poll_position").playback_position().ok();
|
|
let position = self.playback_position().ok();
|
|
```
|
|
|
|
**Après** : Un seul appel
|
|
```rust
|
|
let position = self.playback_position().ok();
|
|
```
|
|
|
|
## Problèmes restants (NON CORRIGÉS)
|
|
|
|
### Services OpenHome sur-sollicités
|
|
|
|
Les services suivants sont appelés trop fréquemment (100-300ms au lieu de 500ms+) :
|
|
- **Playlist:TransportState** (~150ms) - utilisé par `playback_state()`
|
|
- **Playlist:IdArray** (~320ms, irrégulier) - utilisé par les opérations de queue
|
|
- **Product:SourceXml** (~130ms) - vérification de source active
|
|
- **Product:SourceIndex** (non mesuré) - probablement similaire
|
|
|
|
**Impact** :
|
|
- Surcharge réseau inutile
|
|
- Potentiel de ralentissement avec latence réseau élevée
|
|
- Gaspillage CPU (parsing SOAP)
|
|
|
|
**Solution recommandée** :
|
|
Appliquer le même pattern de cache qu'on a fait pour `Time:Time` à ces méthodes :
|
|
- `playback_state()` → cache TransportState
|
|
- Méthodes de queue → cache IdArray
|
|
- Vérification de source → cache SourceXml/SourceIndex
|
|
|
|
## Tests et validation
|
|
|
|
- Compilation : ✅ Succès (15:38 heure de Paris)
|
|
- Logs analysés : `pmomusic.log` (14:54 UTC = 15:54 Paris)
|
|
- Barre de progression : ✅ Fluide (confirmé par utilisateur)
|
|
- Appels Time : ✅ Espacés de ~1s (au lieu de 0.6-1.8s avant)
|
|
- Warnings abus : ✅ Aucun (< 3 appels/seconde)
|
|
|
|
## Conclusion
|
|
|
|
La régression de la barre de progression est corrigée. Le service `Time` bénéficie maintenant d'un cache intelligent qui évite les appels redondants. Cependant, l'analyse des logs révèle que d'autres services OpenHome souffrent du même problème de sur-sollicitation et mériteraient le même traitement.
|
|
|
|
## Métriques
|
|
|
|
- Temps d'investigation : ~2h (après crash)
|
|
- Crates modifiés : `pmocontrol`
|
|
- Lignes modifiées : ~150 (ajouts + suppressions)
|
|
- Services corrigés : 1/5 identifiés
|