Archives de l’auteur : naholyr

*Breaking New* Streams & 0.9.8: objectMode!

C’est tout frais ça vient de sortir dans la 0.9.8, le support des objets autre que des String ou des Buffer dans les streams !

Tiens pour changer je vais mettre les exemples en coffee-script 😉 (je n’aime pas particulièrement, mais c’est utile d’en voir de temps en temps, vue sa popularité il faut bien s’habituer).

Rappelez-vous, notre classe ArrayReadStream :

class ArrayReadStream extends stream.Readable
        constructor: (array) ->
                super {objectMode: true}
                @_array = array
                @_index = 0
        _read: (n, cb) ->
                process.nextTick =>
                        if @_index < @_array.length
                                cb null, @_array[@_index++]
                        else
                                cb null, null

Imaginons qu’on l’utilise pour un tableau d’objet (exemple typique du résultat qu’on aurait voulu avoir avec un client SQL) :

array = [{name: 'John Smith'}, {name: 'John Williams'}, {name: {first: 'John', last: 'Rambo'}}]
 
s = new ArrayReadStream array
 
s.pipe process.stdout

La nouveauté c’est l’option « objectMode«  qui permet d’activer le support des objets directs.

Jusqu’à la 0.9.7 comprise, Ce code ne fait rien. En effet, les données retournée par _read n’étant ni des Buffer ni des String la lecture s’arrête (sans erreur, ce que je trouve un peu moche d’ailleurs…).

En 0.9.8 en revanche ce code va planter :

[…]
TypeError: invalid data
    at WriteStream.Socket.write (net.js:565:11)
[…]

C’est parce que d’un coup process.stdout se prend dans la tête un truc qu’il ne sait pas écrire. Des objets autre qu’un Buffer ou une String ?

Lire la suite

Le « Monkey Patching », ou l’AOP du pauvre

Le monkey-patch, c’est le fait de pouvoir écraser des attributs, méthodes, etc… au moment de l’exécution. On s’en sert en général à remplacer ou étendre une méthode.

En JavaScript, le monkey-patching est extrêmement simple, puisqu’on peut nativement remplacer n’importe quelle méthode d’un objet par une fonction dynamiquement.

Remplacer une méthode

C’est trivial :

object.method = function () {
  // this === object
  // …
};

Modifier le comportement d’une méthode

Supposons que j’ai la classe « Entity » possédant une méthode « save()« . On a un problème, cette méthode a tendance à enregistrer des données complètement corrompues mais on n’arrive pas à savoir dans quelles conditions ça arrive. Le plus simple serait de pouvoir se « brancher » sur cette méthode pour logger certaines informations afin d’en savoir plus.

Le monkey-patching est une façon simple d’y arriver :

// wrap to avoid global context pollution
(function () {
  // store original method
  var _save = Entity.prototype.save;
  // override method
  Entity.prototype.save = function () {
    log_stack_trace(new Error().stack); // grab a stack trace to know where I've been called from
    log_entity(this); // log entity to check data
    // call original method
    _save.apply(this, arguments);
  };
})();

Lire la suite

Hangout Google+ FR.Node.js #1

Ce vendredi 18/01/2013 aura lieu le premier Hangout de la communauté Google+ FR ⋅ Node.js.

C’est un essai, j’avoue ne même pas savoir exactement comment ça se passe techniquement, donc on va probablement avoir des ratés mais ce sera marrant 😉

Ça démarre « officiellement » à 12h45. Au programme :

  • Live-coding autour des streams
  • Discussion libre

Si ça marche bien et qu’on s’amuse tous, on essaiera de refaire ça régulièrement, ça peut être un format sympa.

Bonne semaine et à vendredi !

Un point sur les streams

Les streams, c’est l’API de gestion de flux de données de Node.js.

Cette API est très élégante car elle mime le fonctionnement des flux à la Unix, avec la notion de « pipe », permettant de définir des éléments de code unitaires qui se contentent de recevoir et/ou publier un type de données.

Imaginons qu’on souhaite faire une requête SQL sur un annuaire, effectuer quelques transformations (mettre le nom en majuscule), puis écrire le tout dans un fichier CSV.

Avec l’API asynchrone standard on pourrait imaginer quelque chose comme ça (évidemment il ne s’agit pas d’API existantes exactement, c’est juste une idée) :

var csv = CSVFile('fichier.csv');
query('SELECT nom, prenom, telephone FROM annuaire', function (rows) {
  rows
    .map(function (row) {
      row.nom = row.nom.toUpperCase();
      return row;
    })
    .forEach(function (row) {
      csv.write(row);
    });
});

Et maintenant, la même avec les streams :

query('SELECT nom, prenom, telephone FROM annuaire')
  .pipe(streamMap(function (row) {
    row.nom = row.nom.toUpperCase();
    return row;
  }))
  .pipe(CSVWriter('fichier.csv'));

C’est à la fois plus court, et plus lisible.

Ça ressemble furieusement à ce qu’on ferait en shell : `select_annuaire | nom_majuscule | csv_append ‘fichier.csv’`.

Note : les promesses auraient pu représenter un bon compromis entre les deux, mais ce n’est pas le sujet ici 😉

Lire la suite

Authentification WebSocket avec les sessions Express 3.x et Socket.IO

Suite à mon premier article complet sur le sujet (« Authentification et WebSocket, avec Node.JS, Express, et Socket.IO »), beaucoup m’ont signalé que les exemples ne fonctionnent plus avec Express 3.x. C’est pas tout ça mais Express est quand-même officiellement en version 3 depuis un petit moment, donc il était grand temps de mettre à jour le code !

Je vous encourage à consulter les commentaires de l’article original (merci à Laurent et Will pour leurs discussions sur ce thème) pour de plus amples informations sur les petites surprises qu’on peut rencontrer 😉

J’en profite pour vous décrire l’intégralité de la manœuvre pour que vous voyez un cas de migration Express 2→3, avec des petites astuces en passant :) Le code est dispo sur github, et chaque étape est accompagnée d’un lien vers le commit correspondant.

Lire la suite

Profiler son application NodeJS

Je me suis essayé à un exercice dont je n’ai pas l’habitude: faire du profilage d’applications. Je n’en ai généralement pas eu besoin, les bottlenecks étant souvent faciles à identifier dans les applications sur lesquelles j’ai travaillé, mais viendra tôt ou tard le jour où on se demande si on ne peut pas simplement « faire mieux ». Il n’y a pas de problème particulier, pas d’URL ou de fonction spécifiquement lente identifiée, et dans ce cas si on veut améliorer les performances il faut qu’on trouve déjà où ça pourrait être amélioré 😉

Je pars d’assez loin, ma seule expérience tient dans XDebug et KCachegrind avec PHP. Expérience plutôt concluante d’ailleurs.

Le paysage est beaucoup moins rose du côté de Node.JS, d’une part à cause du peu d’outils « finis » disponibles. Pour résumer, la plupart des outils que j’ai trouvés me semblent plus utiles aux développeurs de V8 qu’au développeur JavaScript… Si vous avez la flemme de lire ce roman, vous pouvez passer directement à la conclusion où vous trouverez un tableau récapitulatif absolument subjectif 😉

Sommaire

Avertissement

Je préviens les pro du profiling qu’il y aura dans cet article de probables énormités sans doute impardonnables. Je vous demande deux choses: aidez-moi à corriger ces énormités :) mais prenez quand-même le temps de vulgariser à destination des débutants (m’incluant) 😉

Lire la suite

Les domaines dans Node.JS, à quoi ça sert ?

Les domaines sont l’une des grandes nouveautés de Node.JS 0.8.

J’étais un peu circonspect quand je les ai vus arriver, ayant un peu de mal à comprendre le cas pratique auquel ils répondaient. Puis je suis tombé sur un cas dans la vraie vie :) Je vais vous le partager en version simplifiée, et on va voir comment le corriger à l’aide des domaines.

Lire la suite

Maîtrisez Node.JS en 2 jours ;)

Avec ce titre un peu pompeux, je vais tacher aussi de reprendre l’animation de ce blog hyperactif.

Il y a eu pas mal de changements dans ma vie professionnelle, et je développe avec Node quotidiennement aujourd’hui sur un « vrai » projet (du genre qui sera en ligne et rapportera de l’argent, pas du genre localhost:8000), et j’ai donc encore plus de choses à dire, d’autant plus qu’il y a eu pas mal de nouveautés avec la récente 0.8. Mais pour ça il faut juste que je me sorte les doigts du c** pour m’y mettre un peu plus sérieusement 😉

Bref, pour l’instant ce billet servira surtout à faire mon auto-promotion pour vous rappeler que je fais de la formation autour de Node.JS: un atelier pratique sur 2 jours permettant de survoler une bonne partie de la techno et d’aller en profondeur sur les points les plus importants. Ça coûte moins de 1000 euros, et ça passe par l’institut de formation Clever Institut (donc pas de souci pour utiliser le D.I.F., passer tout ça en budget formation, et tous les montages dont vous avez l’habitude).

Il y a pour l’instant 2 inscrits à ma connaissance à l’atelier du 15 octobre, et il y a une autre session prévue en décembre. Autant vous dire qu’avec si peu de monde, on peut largement se permettre de sortir des clous et donc de faire du « sur mesure » si besoin. Je pense que ça reste vrai jusqu’à 4 ou 5 personnes, donc n’hésitez pas à me contacter ou à vous inscrire directement depuis le site, et si jamais vous souhaitez une session avec peu de monde dites-le qu’on décale en décembre si jamais il s’avère que ma pub est efficace 😉

Je suis à votre disposition pour en parler, le programme est sur la fiche mais je vous le remets ici.


Le stage se déroulera au fil des chapitres abordés, autour de la réalisation d’une application simple et fonctionnelle, permettant la mise en application concrète des concepts abordés.
PROGRAMME DE LA 1ERE JOURNEE DE FORMATION
Introduction

  • Présentation de NodeJS
    • Installation et utilisation du REPL
    • Le JS côté serveur, pourquoi ?
    • La « single-threaded event loop », c’est quoi ?
  • API non bloquante: pourquoi faire ?
  • La programmation asynchrone: avantages et pièges à éviter
    • Gérer la soupe de callbacks avec « Async »
  • Les modules: pourquoi, comment ?
  • Structure d’un module
  • Rechercher et installer avec NPM

Une application Web avec Node.JS : atelier

  • Description du projet fil rouge
  • Écrire un serveur avec NodeJS
  • Se simplifier la vie avec « Express »
    • Le routage
    • La vue: choisir le bon moteur de template
    • Gérer les fichiers statiques
  • Tests unitaires et fonctionnels avec « Mocha »
  • Packaging de l’application avec NPM

Bases de données SQL et NoSQL : atelier

  • Les librairies d’accès aux bases de données
  • NoSQL: MongoDB et Redis

PROGRAMME DE LA 2NDE JOURNEE DE FORMATION
La communication en temps réel : atelier

  • Intégration des WebSockets HTML5 avec « Socket.IO »
    • Présentation de la technologie
    • Intégration côté serveur
    • Intégration côté client
  • Communication inter-processus en temps réel:
    • Le pub/sub avec Redis.
    • AMQP dans NodeJS: RabbitMQ et ZeroMQ.

Hautes performances : atelier

  • Cluster: Utiliser tous les processeurs de sa machine
  • Cluster et données partagées: la solution haute performances Redis
  • Bonus spécial troll: comparons avec l’équivalent Apache/PHP

Conclusion et conseils

  • Retour sur les bonnes pratiques de développement NodeJS
  • Veille: Comment faire le tri dans les milliers de modules disponibles ?
  • Distribution du projet fil rouge séparé en étapes pédagogiques.

N’hésitez pas à me poser des questions, ou même à me faire des critiques sur ce programme :)

Et si jamais vous souhaitez me contacter hors commentaire public, j’ajoute une page « contact » :)

Mémo BASH: gestion des process

Ça fait un bail que je n’ai pas posté, je profite de l’écriture d’un mémo interne pour me permettre de le copier-coller ici 😉

Comme ces derniers temps j’ai écrit pas mal de scripts de maintenance Bash, je souhaite partager avec vous mes connaissances sur la gestion des process avec le shell (ce qui est quand-même la principale raison pour laquelle on écrirait du shell, outre la portabilité):

Exécution

$command lance la commande et attend son retour
$command & lance la commande en arrière plan
wait attend la fin de tous les process en arrière plan du process courant (code de retour = 0)
wait $PID attend la fin du process caractérisé par ce PID (code de retour = code de retour du process attendu, s’il y en a plusieurs c’est le dernier)

Signaux

kill -0 $PID échoue si aucun process avec ce PID n’existe
trap $command $signal intercepter le signal et exécuter la command indiquée (idéal pour affecter des commandes de nettoyage en post-execute),
exemple: trap 'echo fin' EXIT INT TERM

Variables spéciales

$$ le PID du process courant
$! le PID du dernier process lancé en arrière plan
$? le code de retour de la dernière commande terminée (dans un trap ça peut être le code de retour du process en cours, très utile)

Redirections

$command 1> $file redirige l’output standard vers un fichier
$command 2> $file redirige l’output erreur vers un fichier
$command 1>&2 tout rediriger vers l’output erreur
$command 2>&1 tout rediriger vers l’output standard
$command &> $file tout rediriger vers un fichier
exec &> $file toutes les commandes exécutées après cet appel verront leurs sorties redirigées vers un fichier (exec est en fait bien plus puissant que ça)

Exemple bidon

#!/bin/bash
(sleep 2 && echo 1 && exit 1) &
PID1=$!
(sleep 4 && echo 2 && exit 2) &
PID2=$!
trap "echo Nettoyage... && kill -9 $PID1 $PID2" INT TERM
trap "echo Terminé (code $?)!" EXIT INT TERM
wait $PID1 $PID2
echo code de retour du sleep: $?

N’hésitez pas à partager vos protips de gros barbu en commentaire \o/

Les formations JavaScript pour devenir un vrai pro

Je vais vous parler aujourd’hui des formations données par Christophe Porteneuve: Git Attitude et JS Attitude.

Avant d’aller plus loin, je tiens à préciser que ce n’est pas un article sponsorisé. Je sais que quand les bloggeurs publient un article sur un sujet potentiellement mercantile, le doute subsiste toujours. Promis, ce n’est pas le cas. Par contre j’ai un intérêt dans l’affaire: Ma société (Clever Age) héberge l’évènemet et a droit à des places gratuites, dont j’ai pu bénéficier cette année. Or il n’y a actuellement pas assez d’inscrits à cette formation que je souhaite (vraiment, mais genre vraiment hein) suivre, et elle risque d’être annulée faute d’inscrits :( donc je vous encourage fortement à vous inscrire :)

JS Attitude & Git Attitude

Concrètement, le monsieur va vous parler – à grands coups de discours très animés, de démos qui font briller les yeux, et de TP qui font saigner les doigts – de JavaScript ou de Git. À chaque fois sous deux déclinaisons: vachement balaise (Git au quotidien, et JS puissant), ou encore plus balaise pour roxer à mort (Git avancé, et JS Guru).

Les prochaines formations pour 2011 sont les suivantes:

Le truc pas cool c’est que c’est toujours un samedi. C’est une nécessité pour l’animateur. En revanche, ça veut aussi dire que quand vous allez négocier avec votre boss pour votre DIF, quand vous allez lui dire « hé, je voudrais écouler mon DIF pour devenir meilleur dans mon travail, et en plus sans rater un jour de boulot » je pense que vous allez vraiment marquer des points :)

Les trucs cool en revanche, c’est que l’atelier est vraiment intéressant, que c’est l’une des formations avancées les moins chères du marché (300€ pour Git au quotidien, 450€ pour JS Guru). Christophe est très transparent sur les tarifs et si ça reste évidemment très cher pour une bourse moyenne personnelle, n’hésitez pas à vous renseigner auprès de votre boite pour le DIF ou le crédit d’impôt au titre de la formation, contrairement à ce que disent certains il est de la responsabilité de votre société de vous aider à monter en compétences !

Focus sur JS Guru

Le programme est ici : JS Guru sur le site JS Attitude.

On va y parler d’amélioration progressive, d’HTML5, de JSON & JSON-P, de MVC côté client avec Backbone et Mustache, des nouvelles API comme le local storage, le local db, l’history, l’appcache, etc… Avec des ateliers vraiment pratiques, vraiment funs (là je ne fais que retranscrire les retours de mes collègues ayant eu la chance d’y participer).

 

Bref, aidez-moi à avoir droit à ma formation, rejoignez les rangs des vrais roxors du JS → Go go go inscription pour le 10 décembre à Lyon !