Étude de cas entrepreneurial micro-SaaS Convertisseur AIFF à MP3 Partie 1
Book a callJ’ai implémenté une première version du code (nommée code0-0), comprenant une route POST /convert qui gérait de manière basique les téléversements de fichiers via Multer et l'exécution de FFmpeg à l'aide de la fonction exec.
Cette première itération a permis de valider le concept, bien que des problèmes liés à la gestion de la file d'attente soient rapidement apparus.
Afin de résoudre ces problèmes, j’ai dû créer une série de tests pour couvrir toutes les éventualités possibles, y compris en cas d'erreurs.
En développement web, on crée des tests pour provoquer une erreur anticipée et vérifier si le type d'erreur retourné correspond à celui attendu.
De plus, j'ai dû faire usage du débogueur pour visualiser comment le code gérait la file d'attente.
Ces opérations ont permis d'identifier les dysfonctionnements présents dans le code.
Au fur et à mesure des itérations de ce processus, j’ai réussi à produire un code fonctionnel, accompagné d'une série de tests permettant d’assurer une couverture maximale du code.
Voici le code final de la première version :
Annexe 4.5
./aiffamp3/aiffamp3.js
Le problème que j'ai dû résoudre était essentiellement que les fonctions rateLimiter et checkLimits s'exécutaient trop tardivement dans le cycle de vie de la requête.
Pour décrire le problème, je vais illustrer ce qui est censé se passer et ce qui s'est réellement passé.
Admettons que 6 utilisateurs envoient une requête chacun pour convertir un fichier AIFF, et que le système est limité à 5 conversions qui peuvent être placées dans la « file d'attente » pour être converties, puis retournées.
La sixième requête devrait être ignorée du point de vue de la file d'attente et du traitement. Les 5 premières requêtes sont mises dans la file d'attente et traitées l'une après l'autre. La file d'attente traite les requêtes qui sont arrivées en premier.
La sixième requête a été traitée malgré le fait que la file d'attente l'ait retirée au mauvais moment du cycle de la requête.
Autrement dit, le traitement des fichiers audio a été lancé avant la mise à jour de la file d'attente.
Les fonctions de mise à jour de la file d'attente étaient placées trop tardivement dans le cycle de la requête.
J'ai dû déplacer les fonctions de vérification et de manipulation de la file d'attente avant le traitement des fichiers audio.
J'ai donc placé les fonctions rateLimiter et checkLimits dans des intermédiaires logiciels (middleware) et les ai positionnées avant l'intergiciel final de conversion.
// Ajoutez des explications brèves pour l'Annexe 4.5 (Première version du code)
Annexe 4.5
./aiffamp3/aiffamp3.js
Les différentes implémentations de la fonction processQueue illustrent des approches variées pour gérer le fichier converti après son traitement par FFmpeg. Voici une analyse de chaque version avec leurs spécificités.
Dans cette version, le fichier MP3 converti est envoyé au client via res.download, permettant un téléchargement direct avec le nom "converted.mp3". Le nettoyage des fichiers temporaires (fichier source et fichier converti) est effectué après l’envoi, assurant une gestion efficace de la mémoire.
Annexe 4.5.3.1
./aiffamp3/ignored/code/auto_download_mp3_queue_function.js
Ici, le fichier converti n’est pas envoyé au client mais sauvegardé localement dans un dossier "converted" avec son nom (.mp3). Un message de confirmation est renvoyé.
Annexe 4.5.3.2
./aiffamp3/ignored/code/auto_save_mp3_queue_function.js
Cette implémentation utilise res.sendFile pour envoyer le fichier converti au client, avec un en-tête MIME ("audio/mpeg") définissant le type de contenu. C’est une méthode simple pour fournir le fichier, avec un nettoyage effectué après l’envoi.
Annexe 4.5.3.3
./aiffamp3/ignored/code/auto_response_mp3_payload_returned_in_body.js
Dans cette version, le fichier est transmis au client en streaming via fs.createReadStream et pipe, réduisant la charge mémoire en envoyant les données par morceaux. Le nettoyage est déclenché une fois le streaming terminé, offrant une approche efficace pour les gros fichiers.
Annexe 4.5.3.4
./aiffamp3/ignored/code/auto_response_mp3_payload_returned_in_body_as_stream.js
Les implémentations diffèrent principalement dans la gestion du fichier converti :
Bien que la conversion reste identique, le choix de la réponse varie selon les besoins. En conclusion, le type de retour dépendra du contexte : en phase de test, je sauvegarde le fichier (comme en 4.5.3.2), tandis qu’en production, je privilégie le téléchargement direct par le client (comme en 4.5.3.1 ou 4.5.3.3).
Pour tester l’API, j’ai généré trois fichiers AIFF de durées variées. Ces fichiers m’ont permis d’évaluer le fonctionnement des conversions pour différentes tailles.
De plus, toutes les requêtes ayant pour objectif de générer certains types d'erreurs ont été validées pour vérifier leur conformité avec les attentes.
Voici la série de tests de la première version :
Annexe 4.6
./aiffamp3/API-testing/01.http
Pour tester l’unique endpoint POST /convert, j’ai configuré l’extension REST Client dans VS Code.
Cela m’a permis d’envoyer des requêtes POST avec des fichiers attachés directement depuis l’éditeur, simplifiant ainsi les tests manuels.
Pour valider la première version de l’API, j’ai effectué une série de tests visant à obtenir une couverture de 100 % des fonctionnalités de la version 1, comme détaillé dans l’annexe 4.6.
Ces tests ont couvert divers scénarios : une conversion réussie (Test 1), le rejet d’un fichier non-AIFF (Test 2), l’absence de fichier (Test 3), le dépassement de la limite de débit (Test 4), la surcharge mémoire (Test 5), un fichier corrompu (Test 6), une taille excessive (Test 7), la limite de la file d’attente (Test 8), et le service de fichiers statiques (Test 9).
J’ai exécuté ces tests sur le code, et ils ont tous réussi, confirmant la robustesse de l’implémentation. Pour m’en assurer, j’ai utilisé le débogueur de VS Code afin d’examiner le flux d’exécution étape par étape, notamment pour les cas d’erreur.
J’ai également simulé des requêtes doublées vers l’endpoint POST /convert pour tester la gestion de la file d’attente, en vérifiant que les fichiers étaient bien traités séquentiellement, sans chevauchement ni crash.
Les résultats montrent que chaque test a atteint les objectifs attendus, validant ainsi le fonctionnement du système, de son système d'erreurs et de ses contraintes.