Contexte
Depuis le refactoring #200f7e7, ChunkSizeMB et ParallelChunks sont les deux seuls paramètres de téléchargement. ParallelChunks contrôle à la fois la concurrence des downloads ET le nombre de fenêtres de read-ahead par fichier ouvert.
Problème potentiel
Le WindowCache est global et partagé entre tous les fichiers ouverts, mais il n'y a aucun sémaphore global sur le nombre de requêtes HTTP Range simultanées. Chaque ReadAheadReader prefetch indépendamment.
Calcul du cas à risque
À l'ouverture d'un fichier, NewReadAheadReader lance ParallelChunks + 1 requêtes simultanées (les ParallelChunks premières fenêtres + la dernière fenêtre pour l'index MKV/MP4).
Avec N fichiers ouverts simultanément (ex: VLC + explorateur + 2e player) :
Requêtes simultanées à l'ouverture = N × (ParallelChunks + 1)
Régime permanent = N × ParallelChunks
Exemple : 4 streams × (4+1) = 20 requêtes Range simultanées vers le même serveur
8 streams × (4+1) = 40 requêtes Range simultanées
Conséquences observables :
- Saturation de la connexion réseau vers le serveur média
- Potentiel rate-limiting ou HTTP 500 côté serveur Plex/Jellyfin/Emby
- Dégradation de tous les streams au lieu d'un seul
Solution proposée
Ajouter un sémaphore global dans le WindowCache (ou le Downloader) qui limite le nombre total de fetches HTTP actifs, quel que soit le nombre de fichiers ouverts :
// Dans Downloader ou WindowCache
fetchSem chan struct{} // capacité = ParallelChunks (global, pas par fichier)
// Dans doFetch, avant la requête HTTP
d.fetchSem <- struct{}{}
defer func() { <-d.fetchSem }()
Ainsi ParallelChunks garde sa sémantique d'origine — concurrence totale maximale — que ce soit 1 ou 10 fichiers ouverts.
Quand implémenter
Seulement si on constate en pratique :
- Des HTTP 500 / rate-limit sur Plex ou Emby avec plusieurs streams simultanés
- Une dégradation mesurable de la qualité des streams existants à l'ouverture d'un nouveau fichier
- Une consommation réseau excessive en pic à l'ouverture
Fichiers concernés
internal/downloader/downloader.go — ajout du sémaphore dans Downloader.Init() et doFetch()
internal/downloader/window_cache.go — ou délégation au Downloader
Contexte
Depuis le refactoring #200f7e7,
ChunkSizeMBetParallelChunkssont les deux seuls paramètres de téléchargement.ParallelChunkscontrôle à la fois la concurrence des downloads ET le nombre de fenêtres de read-ahead par fichier ouvert.Problème potentiel
Le
WindowCacheest global et partagé entre tous les fichiers ouverts, mais il n'y a aucun sémaphore global sur le nombre de requêtes HTTP Range simultanées. ChaqueReadAheadReaderprefetch indépendamment.Calcul du cas à risque
À l'ouverture d'un fichier,
NewReadAheadReaderlanceParallelChunks + 1requêtes simultanées (lesParallelChunkspremières fenêtres + la dernière fenêtre pour l'index MKV/MP4).Avec N fichiers ouverts simultanément (ex: VLC + explorateur + 2e player) :
Conséquences observables :
Solution proposée
Ajouter un sémaphore global dans le
WindowCache(ou leDownloader) qui limite le nombre total de fetches HTTP actifs, quel que soit le nombre de fichiers ouverts :Ainsi
ParallelChunksgarde sa sémantique d'origine — concurrence totale maximale — que ce soit 1 ou 10 fichiers ouverts.Quand implémenter
Seulement si on constate en pratique :
Fichiers concernés
internal/downloader/downloader.go— ajout du sémaphore dansDownloader.Init()etdoFetch()internal/downloader/window_cache.go— ou délégation auDownloader