Mar

Une économie de risque

Il y a de ça six mois, j’ai assisté à un meetup qui creuse la question de la consommation énergétique des différents langages de programmation. Loin de vouloir tomber dans le benchmark-mania qui taraude les esprits des développeurs, l’idée de ce meetup se voulait simple : à des contraintes et exigences programmatiques similaires (ou assez proches), que peut-on dire de la consommation des différents langages qui façonnent les stacks techniques les plus utilisées du marché ? 

L’étude d’AXOPEN (dispo ICInous révèle un constat auquel on pouvait s’attendre : JavaScript n’est pas le plus rapide, il est même carrément le moins rapide.

Maintenant, tout cela se circonstancie bien avec les différents contextes d’usage mais on parle là d’ordres de grandeur. Pour faire simple, si vous exécutez une implémentation d’un même algorithme sous JavaScript et sous Rust, vous allez devoir sacrifier – d’entrée de jeu – jusqu’à deux ordres de grandeur sur le temps d’exécution : JS est alors potentiellement cent (100) fois plus lent que Rust (allez lire l’étude, car tout cela y est bien détaillé).

Rien de si catastrophique, vous prenez peut-être chaque jour votre voiture pour aller au travail, pourtant un vélo est infiniment plus énergie-clément et requiert peut-être à peine autant de temps pour faire votre trajet dans une grande ville.

Il y a toutefois là une question qui se pose, elle se pose aujourd’hui et elle se posera davantage dans le futur, cette question m’a traversé la tête au cours dudit Meetup : quid de la contrainte hypothétique stricte qui fera basculer les développeurs JS à une adhésion complète de Rust ? Entendez : qu’est ce qui ferait migrer les masses des développeurs JS vers d’autres stacks moins énergivores ? Et non, ça ne sera pas l’impulsion d’AWS qui a souhaité convertir ses développeurs JS en Rust :wink:.

Une équation se cache ici, elle est de l’ordre microéconomique : si l’unité d’énergie est la contrainte fondamentale (hypothèse A), la comparaison se fait en vérité entre le prix d’une unité temporelle X de développement/maintenance d’un projet sous JS (ou Rust) et le prix d’une unité temporelle Y d’exécution du programme développé sur une machine. En d’autres mots : tant que la/le commanditaire ou la/le gestionnaire d’un projet de développement logiciel estime qu’il lui revient moins cher d’utiliser un développeur JS que de payer une unité X équivalente de temps d’exécution (en ajoutant le temps de maintenance et d’autres temps de ce type ci), la/le commanditaire/gestionnaire va choisir le langage JS puisqu’il lui faut moins de temps et d’énergie cognitive pour trouver un bon développeur JS qu’un bon développeur Rust. 

Le jour où le prix d’exécution d’un programme JS sur une machine sera trop élevé pour justifier le recours à des stacks technologiques de ce langage, on pensera alors plus sérieusement à faire plus de projet sous Rust (c’est déjà le cas pour nombreux projets, mais je parle de l’échelle dans le secteur du développement applicatif). Pour résumer : l’hypothèse A n’est pas encore tout à fait vraie, l’énergie n’est pas la contrainte fondamentale sur un projet de développement informatique, du moins pas perceptuellement ou directement. Cette hypothèse étant donc peu incluse dans les considérations décisionnelles, le JS peut continuer à faire son bonhomme de chemin.

Celà dit, les dès sont peut-être désormais jetés. Nous sommes peut-être confrontés à la question de ce qu’est la réalité du marché économique : nous étions dans un marché à risque, à savoir un marché où les prix d’énergie étaient encore acceptables et les taux directeurs d’emprunt fournis par les banques centrales étaient bas, on a déjà eu le point d’inflexion, on verra peut-être le changement de comportement qui dicte des décisions plus responsables quant au choix technologiques et qui forcent une gestion des projets informatiques de développement logiciel intégrant l’hypothèse A (ou lui conférant une pondération supérieure).

Un comportement responsable, ce ne sera pas forcément le rejet total de JS, tout comme le rejet définitif de votre voiture n’est probablement pas envisageable dans la décennie à venir. Il pourrait s’agir d’améliorer le langage ou de l’utiliser spécifiquement pour des scénarios applicatifs à faible consommation d’énergie. Il pourrait aussi s’agir tout simplement de se poser la question et lancer des réflexions plus probantes sur les changements qu’elle implique.

Toujours est-il que la question se pose, pas de la manière la plus imposante, mais d’une manière qui le sera davantage à une époque où le Serverless devient plus prégnant ; le Serverless porté sur le Cloud impose la réflexion du coup de consommation énergétique (le calcul étant un proxy à cette consommation).

Mais n’oublions pas le principe suivant : les périodes favorables au risque (fastes) génèrent les idées, les périodes d’atonie en éliminent ; JS ne sera peut-être pas éliminé, mais son existence en tant que telle (dans la configuration actuelle) sera challengée.

 

JS au backend, une inception

La naissance de Node.js était un moment !

Ryan Dahl, qui sortait d’une carrière raccourcie de mathématicien sur la topologie algébrique (j’ai essayé, c’est fun, enfin ça dépend aussi de vos goûts) prend un billet d’avion en direction de l’Amérique du Sud et se fait surprendre par le froid, il revient ensuite et commence à faire de la programmation web et réalise que les sites sont lents et consomment trop d’énergie. Il connaissait Rails (Ruby) et il voyait qu’on pouvait monter un web-server assez rapidement contrairement à ce qui était l’état de l’art sur le reste du marché (où il fallait avoir un File System, des CGI scripts, etc.). Une lib à la place d’un File System, c’est pas plus mal ! La première intuition de Ryan était “Pourquoi traîner un système fichier et sa gestion juste pour répondre à des requêtes ?”. Ce que Ryan constate aussi est que Rails a une superbe évolution mais a gardé un problème (du moins à l’époque) ; à chaque requête, on lock le serveur, autrement dit tant que le traitement de la requête courante n’est pas fini, le serveur se réserve entièrement à son traitement. Zéro concurrency, ça ne fait pas rêver…

 

“Node émane d’un désir de résoudre le problème d’upload et d’afficher le progress-bar de cet upload”, dira Ryan. Maintenant qu’il a commencé à se faire un topo de l’univers du modern-web-development, il rencontre des tentatives par-trop-dysfonctionnelles d’uploader des fichiers via une requête (chose courante aujourd’hui, moins courante entre 2004 et 2008). Sa réflexion s’arrête sur un choix : on tente le long-polling (le serveur n’est pas obligé de répondre immédiatement à une requête) et faire des script-tags progressifs (sur un iframe par exemple) de sorte à ce que, à chaque fois que le serveur reçoit un événement, on puisse y répondre mais sans bloquer tout le serveur. Comprenez : le serveur a une notion des évènements qu’il expérience mais il répond quand-il peut. Ryan commence à concrétiser son idée sur Ruby, puis réalise que c’est lent – et d’autant plus lent qu’il rajoute du code Ruby – il se résout à utiliser C. L’amélioration de performance est juste frappante. Son amour pour Ruby demeure mais il doit le rejeter et ce n’est pas une décision facile pour lui. Il commence par explorer les alternatives et il ira regarder ce qui était possible dans l’univers web-server sur d’autres langages. La conclusion : pas grand chose qui ressemble à ce qu’il cherche, il se dit alors qu’il va devoir faire son propre truc. Et puis, le moment sonna !

Vous pouvez revivre et continuer cette histoire passionnante sur cette vidéo (https://www.youtube.com/watch?v=SAc0vQCC6UQ).

Javascript, c’est un langage hyper-utilisé, libre (en syntaxe et en écosystème) et dont la performance sera améliorée en utilisant en background du C.

En 2009, sort la 0.1.0 de Node.js puis en 2010, c’est au tour de la première version stable : la 0.1.1.4. On en pense ce que l’on veut, le succès de Node.js a été très peu rivalisé en termes d’adoption et d’expansion de l’écosystème. Les annales du Software Engineering n’ont pas beaucoup d’histoires où une technologie passe de zéro à la domination d’un marché en l’espace de 10 ans (quoique, je serais curieux de faire l’histoire de ces moments révolutionnaires tiens, je rajoute ça à mon backlog !).

 

Une génialité teintée

Toutefois, on pourrait légitimement se dire : tout signifiant qu’un beau succès peut l’être, ce n’est pas la garantie d’un succès pérenne. Personnellement, jusqu’à assez récemment, l’idée même de JavaScript dans le backend me semblait “bizarre”, disons que les raisons sont nombreuses.

Premièrement, là où sur le JS sur le front-end passait en raison de ce qui était un style de développement moins contraignant (en termes de meilleures pratiques et de méthodologie, chose qui a violemment changé depuis au moins 5/7 ans), la “migration” de beaucoup de développeur du frontend au backend a aussi provoqué le “transfert” d’une  culture JS moins imprégnée par les notions de conception logicielle (architecture, DDD, tests, etc.). J’en énerve peut-être plus d’un, surtout ceux qui se sont acharné comme des fous pour faire de la Craftsmanship sur du JS mais la réalité – selon mon jugement, certes – est que le JS est moins avancé sur l’adoption de cette philosophie qu’un certain Java, C# ou Haskell. La bonne nouvelle est que l’on voit le changement : l’univers JS quitte l’attitude “hacky” et “whatever works” et s’embarque dans le “fonctionnel et propre”.

Deuxièmement, il ne s’agit pas seulement de culture développeurs. Le JS, un peu far-west pour ainsi dire, se dirige désormais vers la civilisation, tout au bénéfice d’un style de développement entreprise-compatible. Si le JS était “far-west”, c’est qu’il est né et est resté longtemps dans une zone du logiciel innovative de la bubble IT autour de l’an 2000, le passage à des codes et moeurs Software moins “hacky” (pour ne pas dire “plus bureaucratique”, car cet épithète trahirait une vraie définition des notions du code artisanal bien compris) relève d’une nécessité d’adoption par l’univers des grandes entreprises qui préfèrent un code maintenable à un code innovatif, et là, la liberté native du JS va laisser plus d’espace à la stabilité.

Troisièmement, en restant sur le thème de la liberté : le langage est multi-paradigme (et non, il n’est pas orienté objet, pas comme un Java par exemple). Les langages multi-paradigmes ont une difficulté : sur le même projet, et pour cinq hypothétiques développeurs impliqués, vous pouvez avoir presque cinq styles différents d’écriture de code ; la remarque est plus vraie lorsque lesdits développeurs collaborent sur le code à des époques différentes et sans avoir été soudés par une culture commune du développement (transmise de manière vivante, par un lead ou d’autres développeurs, la documentation ne marche pas dans ce cas-ci, je suis désolé). J’ai vu des projets où le git blame révèle une archéologie inédite de contributions où l’un a essayé de faire de l’OOP-à-la-Java, où l’une a tenté de faire du functional programming, où le troisième a été dans le prototype-hacking, où le quatrième a fait un certain combo des trois pour résoudre un bug et la cinquième a fait du scripting, etc. 

Il y a quelque part une frontière où la liberté entrave la maintenabilité. Sur ce projet là par exemple, cette frontière a été franchie, comprenez : ce n’est pas la combinaison de ces approches qui dérange, c’est le fait que des régions de codes soient faites sur des approches différentes et non-harmonisées. Sur combien de projets JS la frontière a été franchie ? Je n’en sais rien, mais je suis prêt à parier que le pourcentage est significatif.

Quatrièmement, le JS n’est pas un langage typé, plus précisément, c’est un langage dynamiquement typé. Un code dynamiquement typé est un code qui s’exécute moins vite, mais c’est aussi un code qui est moins lisible et qui possède moins d’expressivité business. A partir de 2012, Typescript a fourni une solution à ce problème. Seulement, comprenons que Typescript n’est pas Javascript, tout superset qu’il en soit, c’est un autre langage, avec une autre trajectoire de progression et d’évolution en tant que langage, ayant des enjeux de comptabilité différents. Mais ok, Typescript c’est quand-même sympa, seulement voilà, Typescript est compile-safe et non runtime-safe, dès lors que le Rubicon de la transpilation est franchie vous êtes dans le territoire far-west du JS où les vieux réflexes des développeurs peuvent se réveiller. Vous avez déjà vu du code JS modifié en Prod ? Avouez-le, si vous étiez encore épargnés cette triste vision, j’ai pas eu la même chance.

Cinquièmement : la sécurité. Peut-être le Big Sad de l’univers JS. Le typage dynamique y joue d’ailleurs une part. L’absence de typage statique ne permet pas de faire du type-check, et ça, ça élargit la surface du vulnérabilité d’un programme. Un autre point pourrait être la gestion des erreurs qui n’est pas superbe dans le langage. Tout cela, c’est ce qu’un bon développeur peut supporter avec un peu d’intention et du processus SecOps. Là où l’intention et le SecOps vont vaciller, c’est au niveau de la gestion des dépendances faites par le Mammouth qu’est NPM et qui reste une vivrière-à-vulnérabilités. On touche là un sujet sensible, car il remet résolument en question l’essence de l’open-attitude du langage : sacrifier la liberté pour la sécurité (sans jeu de mots politique) ? Ce n’est toutefois pas absurde de se poser la question, puisque le passage JS-entreprise suppose un effort de plus en plus considérable pour vérifier des librairies importées de la part des organisations qui adoptent le JS en backend (qui dit backend dit SLA, SRE, intégrité des données et intégrité business, etc.).

Je dois pouvoir penser à d’autres inconvénients du JS en backend, mais l’objectif n’est pas d’être exhaustif mais de montrer que le succès du JS-on-the-server est un compromis technologique qui est, comme tous les autres compromis technologiques, un fait non pas de la technologie elle-même mais du (mauvais) recours à la technologie. Voici un petit exercice ludique : Sur les cinq point susmentionnés, posez-vous les questions suivantes :

  1. Lesquels avez-vous rencontré dans vos expériences ?
  2. Lesquels êtes-vous en train d’expérimenter dans votre expérience courante ?
  3. Comment pourriez-vous faire la différence ?

Vita est milicia super terram

La technologie est un compromis, ai-je dit. Bon, déjà, philosophiquement parlant, la Technologie est un compromis entre l’Humain et la Nature. S’agissant du Software, l’idée même qu’on puisse avoir une technologie qui soit tout-terrain, universellement parfaite, absolue de toutes faiblesses et regrets, voilà une fantaisie ether-iale sans lien avec la pratique de l’ingénierie.

Faites votre compromis, mais sachez que c’est un choix !

Celà dit, on doit boucler cette boucle : le JS a eu un succès qui est expliqué par un contexte socio-économico-technique donné, beaucoup de darwinism, mais le darwinism est aussi synonyme de beaucoup d’aléas et de chance (le langage aurait pu être un dérivé de Lisp si Java n’avait pas vendu le rêve sur-sublimé de l’OOP, petite anecdote, mais pour un autre jour).

Vous n’aimez pas le bloquant, vous faites quelque chose comme un micro-service et vous n’avez pas des traitements CPU-intensifs, vous avez un scénario métier qui ne requiert pas un typage très avancé et vous êtes à même d’avoir les réflexes sécurité : JS sur le backend peut vous convenir ! Autrement, vous voulez mieux penser votre choix, non pas forcément pour rejeter mais pour comprendre votre potentiel de symbiose avec ce langage et sa sphère.

D’une certaine manière, la liberté du JS au backend révèlera vos faiblesses d’organisation et de pratiques. Si les forces et apports de cette technologie ne compensent pas et si vous n’êtes pas prêts à vous améliorer dans vos pratiques alors vous voulez être cadrés par un autre choix technologique.

Ceci était un regard critique de mon gagne pain, on aura d’autres articles pour bien vendre JS, ne vous inquiétez pas 😀 !

 

Faical OUDBIB

Related Posts

Leave A Comment