C'est quoi CloudUp ? • Un site en Node.js – créé entre autres par T.J. Holowaychuck • Fonctionnalité principale : télécharger dès que l'upload commence • C'est aussi un super prétexte pour parler de streams
Et donc, les streams ? • Une autre façon de gérer un résultat asynchrone : – Asynchrone : le résultat d'une opération – Événements : un ensemble de résultats, dans un ordre imprévu – Flux : un résultat éclaté en paquets arrivant dans l'ordre
Et donc Node.js ? • Module stream • Classes de base : Readable, Writable • Implémenter ses propres streams : hériter de Readable, Writable, Duplex, Transform… enjoy ! – RTFM
Attention à la gestion d'erreurs ! • Les streams sont des EventEmitter – Événement spécial « error » – Crash si pas écouté • « pipe » NE CATCHE PAS LES ERREURS – Écouter « error » sur TOUS les flux – Une erreur est vite arrivée (sockets)…
Ça déborde ! • Scénarios de saturation : – Des données prête dans une readable, qui s'accumulent car personne ne lit Accumulation de données (readable)
Ça déborde ! • Scénarios de saturation : – Des données prête dans une readable, qui s'accumulent car personne ne lit • Buffering (Google: « Streams under the hood ») • highWaterMark Accumulation de données (readable)
Ça déborde ! • Scénarios de saturation : – Le writable n'est pas prêt mais on insiste pour lui balancer des données On essaie d'écrire mais on pousse sur le bouchon (writable)
Ça déborde ! • Scénarios de saturation : – Le writable n'est pas prêt mais on insiste pour lui balancer des données • Retour booléan de « write() » • Événement « drain » On essaie d'écrire mais on pousse sur le bouchon (writable)
Ça déborde ! • Ces règles sont facultatives – Les implémentations ne tiennent pas forcément compte de « highWaterMark » – L'utilisateur est libre de ne pas tenir compte du retour de « write() »
Ça déborde ! • Ces règles sont facultatives – Les implémentations ne tiennent pas forcément compte de « highWaterMark » – L'utilisateur est libre de ne pas tenir compte du retour de « write() » – Assumez les conséquences Et ça c'est ta RAM
OK c'est cool ! • Un « chunk » on ne peut pas en faire grand- chose – Exception : « objectMode » mais on n'a pas trop le temps là • La plupart du temps on doit attendre la fin du flux pour commencer à en faire quelque- chose – Doin it wrong
Ah c'est pas cool en fait ? • C'est pour traiter des flux d'information – Use-case : upload • OK mais l'upload je sais déjà gérer… • Et stocker le fichier à deux endroits en même temps, à mesure qu'il s'uploade, tu sais faire ?
Ah c'est pas cool en fait ? • C'est pour traiter des flux d'information – Use-case : upload • OK mais l'upload je sais déjà gérer… • Et lancer un download au fur et à mesure que ça upload ?
Ah c'est pas cool en fait ? • C'est pour traiter des flux d'information – Use-case : upload • OK mais l'upload je sais déjà gérer… • Et lancer un download au fur et à mesure que ça upload ? • Il y en a qui montent des startups avec ça !
Implémentation • Implémentation naïve : – Garder la request de l'utilisateur 1 en mémoire – « pipe » vers la response de l'utilisateur 2 • Problèmes : – Plusieurs uploads ?
Implémentation • Implémentation naïve : – Garder la request de l'utilisateur 1 en mémoire – « pipe » vers la response de l'utilisateur 2 • Problèmes : – Plusieurs uploads ? • Un hashmap des requests en mémoire
Implémentation • Implémentation naïve : – Garder la request de l'utilisateur 1 en mémoire – « pipe » vers la response de l'utilisateur 2 • Problèmes : – Plusieurs uploads ? – Plusieurs downloads d'un même upload ?
Implémentation • Implémentation naïve : – Garder la request de l'utilisateur 1 en mémoire – « pipe » vers la response de l'utilisateur 2 • Problèmes : – Plusieurs uploads ? – Plusieurs downloads d'un même upload ? • Ce qui est déjà téléchargé a été lu depuis la request,et ne peut être re-lu • Stocker ce qui a déjà été lu, faire un système de reprise…
Implémentation • Implémentation naïve : – Garder la request de l'utilisateur 1 en mémoire – « pipe » vers la response de l'utilisateur 2 • Problèmes : – Plusieurs uploads ? – Plusieurs downloads d'un même upload ? – L'occupation mémoire ?
Implémentation • Implémentation naïve : – Garder la request de l'utilisateur 1 en mémoire – « pipe » vers la response de l'utilisateur 2 • Implémentation un peu plus maline : – Module « pending-streams »
Implémentation • Implémentation naïve : – Garder la request de l'utilisateur 1 en mémoire – « pipe » vers la response de l'utilisateur 2 • Implémentation un peu plus maline : – Module « pending-streams »