Node.js passe en version 0.6.0 et arrive sous Windows

Posté par  (site web personnel) . Modéré par Nÿco. Licence CC By‑SA.
Étiquettes :
27
5
nov.
2011
JavaScript

Node.js est un environnement JavaScript côté serveur, sous licence MIT. Sa particularité est son approche asynchrone pour faciliter la montée en puissance dans des contextes avec beaucoup d’entrées‐sorties, notamment réseau. En pratique, il se compose :

  • d’un interpréteur JavaScript, à savoir V8 ;
  • de require(), un chargeur de modules compatible CommonJS ;
  • d’une bibliothèque standard, volontairement restreinte (une sorte de libc JavaScript où tous les appels sont asynchrones) ;
  • d’un ensemble de conventions : par exemple, les fonctions de retour indiquent toujours en premier paramètre si l’appel s’est bien passé, et dans le cas contraire, quelle a été l’erreur ;
  • et d’un exécutable, « node », pour lancer tout ça.

La version 0.6.0 est sortie aujourd’hui et apporte quelques nouveautés de taille (plus de détails en seconde partie) :

  • la prise en charge de Windows en utilisant les I/O Completion Ports (IOCP) ;
  • un répartiteur de charge entre plusieurs processus Node.js intégré ;
  • des moyens de communications entre des processus Node.js plus efficaces ;
  • des améliorations du débogueur en ligne de commande ;
  • des bindings pour la zlib ;
  • la mise à jour de V8, passant de la version 3.1 à la 3.6.

La prise en charge de Windows, sans dégrader les performances pour les UNIX, a pris plus longtemps que prévu. Cela a fortement retardé la sortie de cette version, mais Ryan Dahl, son créateur, souhaite sortir la prochaine version stable de Node.js (la v0.8.0) pour janvier 2012.

Prise en charge de Windows

Node.js 0.4 pouvait déjà tourner sous Windows avec MinGW, mais les performances n’étaient pas là. En effet, Node.js utilise les bibliothèques libev et libeio, pour gérer sa boucle événementielle. Celle‐ci repose sur des mécanismes comme epoll ou kqueue sur les UNIX, qui restent efficaces même quand le nombre de descripteurs de fichiers est élevé (plusieurs milliers). En revanche, la version compilée pour Windows se retrouve à utiliser select, qui est lent dans ces conditions.

Windows possède lui aussi un système capable de tenir efficacement de fortes charges avec une latence faible : les I/O Completion Ports, mais ceux‐ci ne sont pas basés sur des descripteurs de fichiers. Ryan Dahl a donc décidé d’écrire une bibliothèque, la libuv, qui permet d’abstraire ces différences entre les différents systèmes d’exploitation.

Ainsi, le code de Node.js v0.6 est générique et toutes les différences de comportement entre Windows et les UNIX sont gérées au niveau de la libuv. Celle‐ci fait bien entendu appel aux bibliothèques libev et libeio sous UNIX, et aux I/O Completion Ports sous Windows, pour garantir les meilleures performances dans les deux mondes.

Répartition de charge entre plusieurs processus Node.js

Une instance de Node.js tourne dans un seul fil d’exécution (thread) d’un seul processus, et ne peut donc pas tirer pleinement profit de la puissance de calcul des ordinateurs actuels qui possèdent plusieurs processeurs et plusieurs cœurs par processeur. La solution consiste à lancer plusieurs instances de Node.js et, depuis la version 0.6, l’API cluster permet de faire cela simplement. Elle offre la possibilité de créer plusieurs instances esclaves à partir d’une instance maître, et de partager des ports TCP entre les instances esclaves. Cela peut, par exemple, servir à répartir des requêtes HTTP entre les instances esclaves.

Meilleure communication entre processus Node.js

« child_process.fork » lance un nouveau processus Node.js et ouvre un canal de communication entre le processus courant et le nouveau processus. Ces processus peuvent s’envoyer des messages avec send(), sous la forme d’un objet JavaScript, et les recevoir avec « on(message, callback) » :

var cp = require('child_process');
var n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

Et on pourrait avoir le code suivant dans « sub.js » (qui va être exécuté par le fils) :

process.on('message', function(m) {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

Débogueur en ligne de commande amélioré

Node.js propose un débogueur en ligne de commande qui s’appuie sur celui de V8. Il permet d’attacher des points d’arrêt, d’avancer en pas à pas, d’afficher la backtrace et le code en cours d’exécution, de montrer les valeurs des variables et d’exécuter du code JavaScript dans le contexte courant. La documentation donne la liste détaillée de toutes les commandes.

Bindings pour la zlib

Le nouveau module zlib prend en charge les algorithmes de compression gzip et deflate. Il fonctionne en utilisant les flux de Node.js.

Voici un exemple tiré de la documentation :

var gzip = zlib.createGzip();
var fs = require('fs');
var inp = fs.createReadStream('input.txt');
var out = fs.createWriteStream('input.txt.gz');

inp.pipe(gzip).pipe(out);

Mise à jour de V8

V8 est l’interpréteur JavaScript développé par Google pour Chrome et est au cœur de Node.js. La mise à jour de V8 apporte ainsi de meilleures performances (notamment au niveau du ramasse‐miettes — garbage collector —) et une stabilité accrue.

À ce sujet, Ryan Dahl envisage de synchroniser les sorties de Node.js sur celles de V8, toutes les 6 semaines.

Aller plus loin

  • # Programmation asynchrone

    Posté par  (site web personnel) . Évalué à 7.

    Si ce mode de programmation (asynchrone avec callbacks) vous intéresse et que vous préférez Python à Javascript, vous pouvez regarder du côté de Twisted.

    Depuis le site de Twisted on trouve notamment un excellent tutoriel dont la première section concerne les avantages de la programmation asynchrone, et s'applique donc aussi à Node.js.

    • [^] # Re: Programmation asynchrone

      Posté par  . Évalué à 1.

      Dans un domaine similaire, programmation événementielle en Python, y'a aussi ClusterShell.

    • [^] # Re: Programmation asynchrone

      Posté par  (site web personnel) . Évalué à 3.

      Je mentionne Erlang aussi, où le passage de message entre les processus est quelque chose d'extrêmement facile (et naturel, puisqu'il n'y a pas vraiment d'état global partagé). Et, en bonus, c'est un langage fonctionnel (JS aussi certes, mais dans une moindre mesure).

      L'exemple de code de la dépêche deviendrait, en Erlang:

      loop() ->
          receive
             {Pid, M} -> io:format("CHILD got message: ~p", [M]),
                         Pid ! {self(), foo, bar}, % On envoie une réponse au parent
                         loop()
          end.
      
      run() ->
          Pid = spawn(fun loop/0), % Lance un nouveau processus
          Pid ! {self(), {hello, world}}, % On envoie un message au nouveau processus
          receive % On attend pour une réponse
              {Pid, M} -> io:format("PARENT got message: ~p", [M])
          end.
      
      
    • [^] # Re: Programmation asynchrone

      Posté par  . Évalué à 1.

      Sinon, en python, jetez un oeil à fapws (http://www.fapws.org).

    • [^] # Re: Programmation asynchrone

      Posté par  (site web personnel) . Évalué à 3.

      Puisqu'on en est à citer la concurrence :
      Pour ceux qui aime Java il y Netty (Duke's choice award à Java One 2011 et finaliste du challenge USI 2011)

      Et pour les hommes, les vrais, il y a Akka ;)

      My 2 cents...

      • [^] # Re: Programmation asynchrone

        Posté par  . Évalué à 1.

        Ca a l'air simple!

        // Configure the client.
        62          ClientBootstrap bootstrap = new ClientBootstrap(
        63                  new NioClientSocketChannelFactory(
        64                          Executors.newCachedThreadPool(),
        65                          Executors.newCachedThreadPool()));
        66  
        67          // Set up the pipeline factory.
        68          bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
        69              public ChannelPipeline getPipeline() throws Exception {
        70                  return Channels.pipeline(
        71                          new EchoClientHandler(firstMessageSize));
        72              }
        73          });
        74  
        
        
    • [^] # Re: Programmation asynchrone

      Posté par  . Évalué à 1.

      Je ne me souviens plus très plus très bien mais POE pour perl pourrait être utilisé pour ça, non ?

      Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

  • # NodeJS <=> Php ?

    Posté par  (site web personnel) . Évalué à 1.

    NodeJS est son propre serveur. Il a ainsi droit à son propre port et il a le devoir de gérer lui-même les connexions clients.

    Peut-on utiliser NodeJS comme Php ? Apache (ou autre serveur web) traite toutes les connexions comme avec Php. NodeJs ne ferait que s'exécuter.

  • # Node.js is cancer!

    Posté par  (site web personnel) . Évalué à 6.

    http://teddziuba.com/2011/10/node-js-is-cancer.html

    En gros : ça « scale » pas, ça dit merde à l'héritage unix, et en plus, c'est du javascript.

    • [^] # Re: Node.js is cancer!

      Posté par  (site web personnel) . Évalué à 3.

      En un point moins gros, il reproche à node.js de ne pas utiliser un vrai serveur http en front-end, et d'utiliser javascript qui a des performances catastrophiques.

      "La première sécurité est la liberté"

    • [^] # Re: Node.js is cancer!

      Posté par  (site web personnel) . Évalué à 2.

      Mouai mouai mouai...

      Je ne suis pas bien d'accord (surement parce que je bosse sur un projet node.js depuis plus d'un an maintenant, je dois être un peu biaisé...).

      Effectivement, si tu utilise Node.js pour résoudre un problème pour lequel tu aurais pus de façon complètement interchangeable utiliser PHP , Python, Perl , Ruby, un CGI servit par un vrai serveur web, et bien... YOU'RE DOING IT WRONG!

      Node.js est pertinent quand tu ne peux pas utiliser un serveur web classique, par exemple si tu veux utiliser les Websockets, ou tout autre connexion persistante. Et je ne pense pas que la scalabilité soit en soit une bonne raison pour utiliser Node.js.

      Quant a l'argument "It's fucking Javascript!!!" ... Les années 90 viennent d'appeler, elles voudrait récupérer leur troll.

      • [^] # Re: Node.js is cancer!

        Posté par  . Évalué à 0.

        Donc node.js c'est pour écrire un serveur complet comme on pourrait le faire en php, pyhon, perl, ruby, ...

        si tu utilise Node.js pour résoudre un problème pour lequel tu aurais pus de façon complètement interchangeable utiliser PHP , Python, Perl , Ruby, [...] et bien... YOU'RE DOING IT WRONG!

        • [^] # Re: Node.js is cancer!

          Posté par  (site web personnel) . Évalué à 1.

          Tu as rate le seule passage important: "...servit par un vrai serveur web"
          Et si tu écris un serveur complet en php alors que tu pourrais le faire servir par apache, you're doint it wrong aussi.

  • # Mais pourquoi

    Posté par  . Évalué à 2.

    Javascript dans le navigateur c'est déjà très laid, et la plupart des devs préféreraient un langage mieux foutu si ils avaient le choix.
    Mais alors sorti de ce contexte il faut être carrément maso pour vouloir coder une appli avec ça !!!

    • [^] # Re: Mais pourquoi

      Posté par  . Évalué à 1.

      Je pense que c'est lourd de devoir manipuler je ne sais combien de langages pour faire du web donc s'ils peuvent diminuer ce nombre je pense que ça peut en intéresser plus d'un.

      De plus j'avais lu quelque part qu'avec Node.js le choix de ce qui s'exécute sur le client ou sur le serveur est trivial.

      Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: Mais pourquoi

      Posté par  (site web personnel) . Évalué à 3.

      Javascript dans le navigateur c'est laid a cause du poids de l'histoire. En soit, le Javascript n'est pas pire qu'un autre. Il est parfois farceur, mais tous les langages ont leurs petites blagounettes.

      Son vrai point fort c'est qu'avec ses nested functions et ses closures, il est très bien adapté a la programmation événementielle, ce qui fait pas mal sens sur un serveur (c'est peut-etre parce que je bosse avec, mais je trouve un code node.js vachement plus lisible qu'un code python/twisted (et pourtant j'adore le python!)).

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.