Article pour la sortie de Vert.x 3

Développement d'applications asynchrones pour la JVM

a marqué ce sujet comme résolu.

Bonjour,

Je suis en train de préparer un article pour la sortie de Vert.x 3, et il faut bien se rendre à l'évidence, j'ai pas mal besoin d'aide, notamment pour trancher dans le vif et supprimer certaines parties. L'article est beaucoup trop long à mon goût et surtout j'ai peur qu'il soit pénible à lire. Pour ma part je manque un peu de recul pour savoir quelles parties supprimer, je vous laisse juger.

Merci d'avance pour l'aide apportée, depuis des corrections orthographiques ou quoi que ce soit d'autre.

Bonjour à tous,

Ce 22 juin 2015, la version 3 de Vert.x a vu le jour. L'occasion pour moi de vous présenter cette boîte à outils pour la Java Virtual Machine.

Qu'est-ce-que Vert.x, en quelques mots ?

Il s'agit d'une boîte à outils polyglote pour construire des applications réseau (web, par extension) asynchrones pour la JVM. Si vous connaissez Node.js, ces mots devraient vous être relativement familiers. Et d'ailleurs pour l'anecdote, la première version de Vert.x s'appelait Node.X… Rien d'innocent là-dedans.

Le cœur de Vert.x est développé sous la coupe de la fondation Eclipse, les projets "satellites" (extensions, support de différents langages, clients asynchrones pour différents SGBD, …) sont des projets 100% communautaires. L'ensemble est disponible sous licence Apache 2.0.

L'idée fondatrice de Vert.x est de construire son application par ensemble de petites briques, appelées micro-services, qui peuvent fonctionner sur une même machine ou sur des machines différentes à travers le réseau de façon transparente pour le développeur. De même, chaque brique peut-être, sans aucun effort et surtout sans aucun changement dans son code, déployée sous forme d'une ou plusieurs instances. Permettant ainsi une grande scalabilité des applications.

Avant de rentrer plus en détail dans le fonctionnement de Vert.x, écrivons le sacro-saint Hello, World.

En Java 8 :

1
2
3
4
5
6
7
public class Server extends AbstractVerticle {
  public void start() {
    vertx.createHttpServer().requestHandler(req -> {
      req.response().end("Hello from Vert.x!");
    }).listen(8080);
  }
}

Son petit frère en Javascript :

1
2
3
4
var vertx = require('vertx');
vertx.createHttpServer().requestHandler(function (req) {
  req.response().end("Hello from Vert.x!");
}).listen(8080);

Leur cousin en Groovy :

1
2
3
vertx.createHttpServer().requestHandler({ req ->
  req.response().end("Hello from Vert.x!")
}).listen(8080)

Enfin, le petit dernier de la famille, monsieur Ruby :

1
2
3
vertx.create_http_server().request_handler() { |req|
  req.response().end("Hello from Vert.x!")
}.listen(8080)

Pour les cousins germains que sont Scala, Python, Clojure, Ceylon, … Il faudra attendre la version 3.1 de Vert.x.

Deux points majeurs à noter dans ce tout petit bout de code.

En premier lieu, il n'y a pas besoin d'énormément de code pour préparer un serveur HTTP, le lancer et lui dire comment il doit répondre aux requêtes HTTP. Encore heureux, c'est un peu le but du jeu et l'exemple n'est pas bien complexe.

Ensuite, on remarquera la cohérence de l'API dans les différents langages. L'équipe de Vert.x a choisi de conserver une API très semblable (qu'elle qualifie "d'idiomatique") dans les différents langages pour lesquels elle est disponible. Ainsi on retrouve un objet vertx, et les méthodes createHttpServer, requestHandler et listen.

Si on regarde dans le détail la méthode qui décrit comment le serveur doit répondre aux requêtes HTTP, on se rend compte qu'elle prend cependant plusieurs formes différentes :

  • une lambda expression en Java 8
  • une fonction anonyme en Javascript
  • une Closure en Groovy
  • un bloc en Ruby

Ce sont les moyens d'expression d'une fermeture (ou clôture, en Angais closure) dans ces trois langages. C'est vraiment le souhait de l'équipe de développement de Vert.x. Exporter, dans chaque langage supporté, les mêmes primitives à l'aide des possibilités offertes par le langage. Nous reviendrons sur le "comment" un peu plus tard dans cet article.

Revenons sur ce qui donne à Vert.x sa particularité en parcourant la description présente dans la documentation officielle.

Vert.x est reactive (réactif)

Le paradigme de programmation choisi pour l'API de Vert.x est event-driven et non-blocking. Qu'est-ce-que cela signifie en pratique ?

En gros ça veut dire "ne m'appelez pas, c'est moi qui vous appellerai". On écrit son code de façon descriptive, en expliquant ce qu'il faut faire, et dans quel cas le faire. Ce que l'on écrit, ce sont des "réactions" à des stimuli (event-driven). On n'appelle pas de primitives directement (ou très rarement), mais on écrit plutôt :

Quand une requête te parvient, voici comment la traiter.

Encore une fois, ce n'est pas nouveau dans le monde de ces technologies asynchrones.

Pourquoi cette approche ? Et sous le capot, comment ça fonctionne ?

En réalité, le constat de base de tous ces nouveaux outils de développement d'applications asynchrones (Node.js, netty, undertow, akka, Tornado, …) partent d'un même constat : une application fonctionnant sur le réseau passe son temps à attendre. Mais à attendre quoi, au juste ? A vrai dire, tout plein de choses. Un cas que l'on retrouve fréquemment dans une application web par exemple, est d'interroger une base de données, parfois localisée sur la même machine, parfois sur un point distant du réseau. Dans ce cas, le schéma d'éxécution est le suivant :

  • l'utilisateur fait une requête au serveur
  • le serveur web reçoit la requête, en extrait les informations qui l'intéressent (paramètres, en-têtes, …)
  • le serveur web interroge la base de données (requêtes SQL, procédure stockée, récupération d'un document, d'un set, suivant le type de stockage : SQL ou noSQL ou autre)
  • la base de données (ou plus globalement : le système de stockage) répond au serveur web
  • le serveur web formate la réponse comme il le souhaite (appel d'un moteur de template pour formater une page HTML, marshalling XML, JSON ou autre s'il s'agit d'une API REST, …)
  • l'utilisateur reçoit la requête, le navigateur l'affiche ou la traite (dans le cas d'un appel Ajax par exemple)

On voit donc, que du côté du serveur web, il y a une durée non-négligeable, et surtout non maîtrisable passée à attendre une réponse (dans l'exemple : du système de stockage, mais cela pourrait être des I/O du système, ou encore tout plein d'autres choses).

Or, les serveurs web classiques ("historiques" dirons-nous) et surtout les frameworks associés (Java EE en tête) fonctionnent de la façon suivante : lorsqu'une requête parvient au serveur, le serveur alloue un thread à son traitement. Une fois la réponse envoyée au client, le thread est désalloué.

Et du coup, on a alloué un thread à…

… attendre majoritairement, ce qui est somme toute un peu dommage. Et on a surtout l'impression que ce sont des ressources simplement perdues. Pire encore, si on a besoin de gérer un grand nombre de requêtes en parallèle (un trafic important), il nous faut un grand nombre de threads (un nombre quasi-directement proportionnel au nombre de requêtes que l'on souhaite traiter). Une ressource coûteuse (spécialement en Java)… Et qui semble bien mal employée.

L'idée est donc d'ordonnancer les traitements au lieu de les paralléliser. En partant du principe que les traitements (réels, pas le temps passé à attendre) sont généralement plutôt courts, voire quasi instantanés. Vous en conviendrez, générer un petit bout de page HTML (finalement une bête chaîne de caractère) c'est loin d'être très coûteux.

Ensuite, au lieu d'attendre une réponse, on rend la main. On "enregistre" auprès de Vert.x (ou node, ou autre) le code à appeler et quand est-ce-qu'il sera appelé.

Concrètement, dans l'exemple précédent, le développeur aurait décrit le fonctionnement suivant :

  • quand on te demande une page, exécute cette requête vers la base de données, puis rend la main
  • quand la base de données t'aura répondu, renvoie telle réponse au client (en fonction des données reçues)

Charge maintenant à Vert.x de s'en débrouiller, et d'ordonnancer tout ce petit monde. Le but du jeu étant qu'aucun thread ne soit inactif (en attente d'I/O, …).

Pour ceux que cela intéresse, et qui désireraient en savoir plus on parle de patron de conception reactor.

Ainsi, toute la mécanique de gestion de la concurrence, des threads, etc. est gérée par Vert.x (à l'aide d'une event-loop comme décrit dans l'article cité précédemment). Vous écrivez du code sans vous soucier du contexte dans lequel il sera exécuté. Et même mieux, vous avez l'assurance que pour une même requête, votre code sera toujours exécuté dans le même contexte. C'est la garantie qu'offre Vert.x. Finis les synchronized, les volatile, et autres verrous potentiels. La seule chose dont vous devez vous soucier et de ne jamais (sous aucun prétexte) bloquer la sacro-sainte event-loop (donc rendre la main lorsque vous exécutez une opération qui prend du temps et l'éxécuter de façon asynchrone). C'est la clef du succès.

Pour autant, il serait dommage de n'utiliser qu'un seul thread de votre machine, d'autant plus sur une machine disposant de plusieurs cœurs. Du coup, Vert.x propose (sans que vous n'ayez à vous en préoccuper) par défaut plusieurs event-loops, proportionnellement au nombre de cœurs disponibles sur votre machine. C'est une différence majeure avec Node.js qui pour obtenir le même fonctionnement nécessite d'instancier plusieurs "nœuds".

Cette différence a valu par le passé à Vert.x le petit surnom de "Node.js sous stéroïdes", notamment lorsqu'est sorti ce test de performance réalisé par Techempower.

Les développeurs de Vert.x ont donné à ce mode de fonctionnement le petit nom de multi-reactor pattern par opposition au reactor pattern présenté plus haut.

Vert.x est polyglote

On l'a vu dans l'exemple ci-dessus. Vert.x fournit une API en Java, Javascript, Ruby et Groovy pour l'instant et les développeurs s'attachent désormais à fournir son équivalent en Python, Scala, Clojure et Ceylon.

L'idée, c'est que l'équipe de développement n'a pas envie de prendre partie dans une guerre de langage (qui tourne parfois à la guerre de clochers, …), et se fiche pas mal de "quel langage est le meilleur".

C'est à vous de choisir le langage que vous préférez, ou dans lequel vous vous sentez le plus compétent. De même, étant donné la nature assez peu dogmatique de Vert.x (vous pouvez l'utiliser pour ce que vous voulez, application web, file de messages, event-bus distribué, …) : en fonction du micro-service que vous écrivez, Java peut paraître plus adapté, tandis que pour un autre, Python vous semblera meilleur. Vert.x s'en fiche. "Chat perché".

Vert.x est unopiniated (non-dogmatique)

Un anglicisme barbare. Qu'est-ce-que ça veut dire ?

Un peu de la même façon que l'équipe se fiche pas mal de quel langage est le meilleur, Vert.x n'est pas un framework dans le sens : "il n'y a qu'une bonne façon d'écrire une application". Si vous connaissez Symfony, Rails, Spring MVC, vous savez sans doute de quoi je parle. On a des vues, des modèles, des templates, un moteur de templates, des services, un ORM, …

Ce sont des frameworks extrêmement performants pour conduire votre développement, ils vous fournissent un canvas, balisent le chemin pour vous. Vous écrivez des contrôleurs, des vues, des services, une couche d'accès aux données etc. Ce qui donne une grande cohérence dans les applications écrites à l'aide de ces frameworks et guide parfaitement les débutants vers de bonnes pratiques. Ce qui sont deux arguments de taille.

Vert.x fait tout l'inverse, pour une simple raison : il n'y a pas vraiment d'application-type. Qu'il s'agisse de gérer une application "middle-tiers" ou un serveur d'API REST, Vert.x sera adapté à ces deux tâches, si tant est que vous écriviez votre application correctement.

Ce choix est un choix très fort, d'un coté extrêmement intéressant mais parfois également critiqué. Il faut bien comprendre qu'au contraire de ce qu'on peut penser, Vert.x n'est pas véritablement un framework, mais plus une boîte à outils. Vous avez tous les outils à disposition pour faire absolument tout ce que vous voulez, de façon asynchrone. Par contre, si vous écrivez une application web plus classique (rigoureusement MVC, que je qualifierais de model-driven) vous vous retrouverez sans doute à écrire beaucoup plus de code qu'avec Rails, Django ou Symfony par exemple. A vous de juger !

Légèreté

Vert.x est extrêmement léger. Le noyau de l'API (sans brique additionnelle) pèse à peu près 650kB et ne vient pas avec une méga-tonne de dépendances transitives. Cela n'a l'air de rien, mais dans le monde de la JVM c'est assez rare pour être souligné.

Rapide

Depuis la version 2, les développeurs de Vert.x se sont attachés à en faire un produit performant, capable de tirer profit de la machine sur laquelle il tourne (notamment le nombre de cœurs) sans que le développeur n'ait à s'en préoccuper. Capable également d'une grande scalabilité. En une option, vous pouvez passer d'un thread à plusieurs, sans rien n'avoir à changer au code que vous avez écrit. J'ai cité un test de performance datant de la version 2 de Vert.x, sachez que Vert.x 3 et en train d'être passé au crible pour battre à plates coutures son aîné.

Modulaire

Au contraire de ses aïeux du monde Java EE (Tomcat, JBoss, Websphere, …) Vert.x n'est pas un conteneur d'application (là encore, avantage/inconvénient, à vous de voir en fonction de votre besoin).

Chaque micro-service est une application à part entière. Vert.x sait déployer ces applications (les fameux "micro-services") programmatiquement ou via la ligne de commande, mais rien ne vous oblige à la faire. Vous pouvez tout simplement écrire un main et y coller :

1
Vertx vertx = Vertx.vertx();

Et c'est parti, vous avez accès à la boîte à outil.

Libre à vous d'oganiser vos applications comme vous le souhaitez. En fonction de ce que vous désirez faire.

Si vous choisissez l'approche "service" (appelés Verticle), sachez que vous disposez d'un grand nombre d'outils pour les déployer, programmatiquement ou non.

Vous pouvez ainsi choisir que votre serveur web doit fonctionner sur quatre instances en parallèle et disposer d'une haute disponibilité (high-availability, i.e. Vert.x s'occupe de le redéployer s'il détecte une panne) tandis que votre petit service de supervision devrait quant à lui se contenter de peu de ressources (parce qu'il n'a pas grand chose d'autre à faire qu'envoyer un mail de temps en temps) et que vous le redémarrerez à la main, voire pas du tout. Vous avez besoin d'un autre service, lui beaucoup plus lourd et effectuant des traitement bloquants (parfois on n'a malheureusement pas le choix…), vous allez alors demander à Vert.x de le déployer en tant que worker verticle, lui allouant un thread à part, et surtout pas une event-loop, histoire qu'il ne la bloque pas.

Un Event-Bus distribué

Encore un barbarisme qu'il est nécessaire d'expliquer…

Nous avons vu qu'on pouvait disposer de tout plein de petits services, éparpillés aux quatre coins du réseau sans que cela ne pose de réel problème. Mais que se passe-t-il lorsque ces services ont besoin de communiquer entre eux ?

Réponse simple : on leur colle un serveur web à chacun ? Mmm, oui mais non…

En réalité, Vert.x propose un distributeur de message (ou Message Broker, ou Event Bus en Anglais dans le texte) dont le rôle, vous l'aurez deviné, est de distribuer des messages, des réponses, etc. à tout notre petit monde, un facteur, en gros.

Peu importe que vos services fonctionnent sur la même machine ou sur deux nœuds distincts du réseau. C'est le problème de Vert.x, pas le votre. Vous disposez d'une API pour envoyer et recevoir des messages, Vert.x s'occupe de les distribuer. Il s'agit d'une implémentation du patron de conception publish / subscribe pour les plus curieux.

Quoi de neuf dans la version 3 ?

Gestion des langages alternatifs

L'aspect polyglote de Vert.x est donc un argument important aux yeux des développeurs. Dans la version 2, c'est la communauté qui s'occupait de porter l'API dans le langage de leur choix. Il existait donc un module Groovy, un module Scala, etc.

Approche intéressante mais néanmoins un peu limitée.

Ainsi, dès les prémices de la version 3, l'équipe à fait le choix de générer automatiquement l'API dans tous les langages supportés, à partir du code Java. C'est le projet vertx-codegen. Je ne rentrerais pas dans les détails ici, mais pour ceux que cela intéresse, sachez que son fonctionnement repose sur des templates MVEL et l'Annotation Processing Tool de Java. Ainsi, votre code est analysé lors de sa compilation en Java, et les autres APIs sont générées automatiquement.

C'est un outil important essentiellement pour les développeurs de Vert.x ou de clients tiers (Redis, MongoDB, …) mais pourquoi pas vous ? Si vous écrivez un petit service en Java pour vos besoins et que vous décidez de changer de langage, pourquoi pas utiliser codegen ?

C'est le cas des exemples fournis par Vert.x. Chacun d'eux est automatiquement retranscrit dans l'ensemble des langages supportés par Vert.x.

Exit le système de modules

Que serait une boîte à outils sans outils ? Pas grand chose…

Dans la version 2, Vert.x proposait un système de modules. Par exemple, si vous souhaitiez interagir avec MongoDB, vous deviez utiliser le module vertx-mongodb. Et vous pouviez déclarer votre dépendance à ce module lors du démarrage de votre application, Vert.x allait le chercher, le télécharger, et le lancer tout seul comme un grand.

Le soucis, c'est que ce système de module était propre à Vert.x, avec un format particulier, son propre descripteur, et packagé sous forme de zip.

Intéressant, mais un peu limitant parfois.

L'équipe de développement a donc fait table rase de ce système pour partir du principe que n'importe quelle dépendance pouvait être un module (un jar, une gem, un module CommonJS, …).

Et du coup, repose désormais sur des factories à aller fouiller à la recherche de dépendances. Ainsi, si vous souhaitez utiliser, dans votre code, le module XXX et que vous travaillez en Java, vous allez déclarer une dépendance à ce module (via Maven ou Gradle par exemple) dans votre projet comme vous le feriez dans n'importe quel autre projet. Par contre, si vous souhaitez lancer le module XXX en tant que service (par exemple une base MongoDB embarquée, …), alors vous allez déployer programmatiquement ce service de la façon suivante dans votre code :

1
vertx.deployVerticle("maven:com.mycompany:main-services:1.2::my-service")

La dépendance sera chargée automatiquement au lancement de votre application.

Le développeur dispose du coup d'une plus grande souplesse. Soit il s'agit d'une dépendance forte (il a besoin du service-tiers dans son code) soit d'une dépendance au sens micro-service (j'ai besoin d'avoir une base MongoDB qui tourne quelque part pour mes tests, par exemple).

Une palette d'outils pour les applications web

A l'instar de son prédécesseur Yoke, Vert.x Web fournit un ensemble d'outils à destination des développeurs d'application web pour gérer tout un tas de petites choses dont ils ont systématiquement besoin : la session HTTP, les différents mécanismes d'authentification (Basic, OAuth, …), les cookies, le routage et la déclaration de routes, la lecture de paramètres de requêtes, la gestion de différents MIME-TYPES, les websockets et protocoles assimilés, les moteurs de templates, …

C'est un grand pas pour l'ouverture de Vert.x vers un monde un peu différent, partant du pur "middle-tiers" (services réseau bas niveau) vers des applications qu'on qualifie aujourd'hui de fullstack, un terme un peu flou comme le web nous en réserve parfois mais qui signifie grosso-modo "qui s'occupe de tout" depuis la plomberie de bas-niveau (files de message entre nœuds du réseau, tâches périodiques, reprise sur erreur, …) jusqu'à la présentation de données à des clients modernes (différents moteurs de template, gestion des websockets, …).

Pour faire la comparaison, si vous connaissez Node.js, Vert.x dispose aujourd'hui de l'équivalent d'Express et ses middlewares ou si vous êtes plutôt Ruby, de Sinatra.

Proxifier des services

L'Event-Bus est l'une des pierres angulaires de Vert.x depuis sa première version, et il n'a pas énormément changé dans cette version.

Une des nouveautés introduites cependant, est la possibilité de définir n'importe quel service comme étant invocable (appelable) depuis l'event-bus, simplement en annotant son service et en laissant le compilateur (Java) se débrouiller et générer le code nécessaire.

Cela permet, à l'instar de protocoles comme WAMP ou RPC, d'appeler des méthodes à distance et de façon asynchrone depuis n'importe quel point du réseau.

Conclusion

C'en est terminé de cette présentation de Vert.x, vous l'aurez compris assez similaire à Node.js mais aussi sensiblement différent sur quelques axes majeurs.

Pour aller plus loin

+0 -0

A titre personnel je ne trouve pas le contenu vraiment long. Paradoxalement ce que j'ai le plus apprécié c'est la partie de présentation. Celle sur les nouveautés, pour quelqu'un comme moi qui connaissait peu cet outil, a moins d'intéret.

C'est toute la difficulté de ce genre d'article. Si j'étais toi je profiterai de la sortie pour parler de Vert.x mais j’allégerai la partie sur les nouveautés (si vraiment tu veux réduire).

Honnêtement ça se lit bien. La longueur n'est pas gênante à la première lecture.

Si j'avais un point à noter, je dirais que balancer des "hello world" sans expliquer d'abord que c'est polyglotte me dérange un peu. On se demande ce que ça vient faire en premier.

Sinon, j'ai relevé une coquille :

La seule chose dont vous devez vous soucier et de ne jamais

Est de ne jamais (il manque un s).

Pour le reste, ça me paraît bon. Et clair, surtout.

Merci pour vos retours.

En effet je vais probablement alléger la partie "Quoi de neuf", je pensais que l'histoire de génération de code pouvait être intéressante, et que la partie web pouvait pousser les gens à s'y intéresser pour créer des applis web. Mais à la rigueur, c'est plutôt à débattre dans les commentaires.

Si j'avais un point à noter, je dirais que balancer des "hello world" sans expliquer d'abord que c'est polyglotte

J'ai pas compris. L'aspect polyglotte est mentionné dans la première phrase du second paragraphe, bien avant les exemples de code.

+0 -0

Je laisse encore l'article en bêta ici même pendant un ou deux jours avant de l'envoyer en publication.

Je vais supprimer purement et simplement la partie sur les nouveautés de la v3 et par contre ajouter un paragraphe sur les NIO / Netty (qui sont à la racine de Vert.x).

+0 -0

Je me concentre uniquement ici sur le fond. Je reviendrai sur la forme quand ce dernier sera bien établi.

Qu'est-ce-que Vert.x, en quelques mots ?

Il s'agit d'une boîte à outils polyglote pour construire des applications réseau (web, par extension) asynchrones pour la JVM. Si vous connaissez Node.js, ces mots devraient vous être relativement familiers. Et d'ailleurs pour l'anecdote, la première version de Vert.x s'appelait Node.X… Rien d'innocent là-dedans.

Si je ne connais pas Node, ça ne m'est pas familier. Je fournirais des exemples de ce que Vert.x permet de faire.

De même, chaque brique peut-être, sans aucun effort et surtout sans aucun changement dans son code, déployée sous forme d'une ou plusieurs instances. Permettant ainsi une grande scalabilité des applications.

Ce n'est pas très clair. Pourquoi voudrais-je avoir deux instances d'un même programme ?

Avant de rentrer plus en détail dans le fonctionnement de Vert.x, écrivons le sacro-saint Hello, World.

Tu devrais détailler ce que l'on va faire. J'imagine que ce n'est pas juste afficher "Hello, World" dans la console. :P

Exporter, dans chaque langage supporté, les mêmes primitives à l'aide des possibilités offertes par le langage.

Le terme "primitive" gagnerait à être explicité.

Vert.x est reactive (réactif)

En gros ça veut dire "ne m'appelez pas, c'est moi qui vous appellerai". On écrit son code de façon descriptive, en expliquant ce qu'il faut faire, et dans quel cas le faire. Ce que l'on écrit, ce sont des "réactions" à des stimuli (event-driven). On n'appelle pas de primitives directement (ou très rarement), mais on écrit plutôt :

C'est un peu flou. Pas mal même. Je ne suis pas sûr que ce soit utile. Tu pourrais commencer la partie à "En réalité, le constat de base de tous ces nouveaux outils de développement d'applications asynchrones".

Encore une fois, ce n'est pas nouveau dans le monde de ces technologies asynchrones.

Pourquoi "encore une fois" ?

On voit donc, que du côté du serveur web, il y a une durée non-négligeable, et surtout non maîtrisable passée à attendre une réponse (dans l'exemple : du système de stockage, mais cela pourrait être des I/O du système, ou encore tout plein d'autres choses).

Justement non, on ne le voit pas beaucoup, parce que tu passes directement de "le serveur web interroge la base de données" à "la base de données répond au serveur web".

lorsqu'une requête parvient au serveur, le serveur alloue un thread à son traitement

J'expliquerais brièvement ce qu'est un thread.

Une ressource coûteuse (spécialement en Java)… Et qui semble bien mal employée.

Que désignes-tu par "ressource" ?

L'idée est donc d'ordonnancer les traitements au lieu de les paralléliser.

J'expliciterais. Ca revient à faire du synchrone, non ?

Ensuite, au lieu d'attendre une réponse, on rend la main. On "enregistre" auprès de Vert.x (ou node, ou autre) le code à appeler et quand est-ce-qu'il sera appelé.

Ca va un peu vite. Tu as dit qu'on ordonnançait les traitements (qu'on les met à la queuleuleu si j'ai bien compris) et là tu dis qu'on n'attend pas une réponse. Mais une réponse de quoi ? Du premier traitement de la file ?

Le but du jeu étant qu'aucun thread ne soit inactif (en attente d'I/O, …).

Ce qui précède sous-entend qu'on a abandonné les threads : "L'idée est donc d'ordonnancer les traitements au lieu de les paralléliser.".

Pour autant, il serait dommage de n'utiliser qu'un seul thread de votre machine

Ce qui précède sous-entend qu'on en utilise plusieurs : "Ainsi, toute la mécanique de gestion de la concurrence, des threads, etc.".

Même en connaissant le principe de la programmation asynchrone, j'ai du mal à suivre cette partie ("Vert.x est reactive (réactif)"). Je peux t'aider à clarifier ça, mais uniquement si tu m'éclaires sur la logique globale. Est-ce ce qui suit ?

  • Synchrone (avec threads)
  • Pourri, donc asynchrone (Node.js)
  • Encore pourri, donc multi-reactor pattern (Vert.x)

Vert.x est unopiniated (non-dogmatique)

Vous avez tous les outils à disposition pour faire absolument tout ce que vous voulez, de façon asynchrone.

Ca, il faut le dire bien avant. Ce n'est que maintenant que j'ai à peu près compris ce qu'était Vert.x.


J'ai fait pas mal de remarques parce que ton article constitue une bonne introduction à l'asynchrone. Du coup, il me semble important de le rendre accessible au plus grand nombre. :)

Pour revenir sur mon incompréhension de Vert.x, je pense qu'elle est due au fait que tu abordes trop rapidement les aspects techniques. Autrement dit, tu devrais développer la partie avant "Vert.x est reactive (réactif)", pour suivre le raisonnement suivant :

  • Vert.x, c'est quoi ?
  • Ca fait quoi ?
  • Ca le fait comment ?

L'impression que Vert.x est une usine à gaz est-elle justifiée ? Autrement dit, j'ai l'impression que cette boîte à outils permet de tout faire.

Merci !

+0 -0

Merci pour tes remarques qui prouvent certainement que le fond est totalement à revoir avant de publier sur ce site.

Je vais voir si j'ai le courage de prendre en compte tout ça.

EDIT : typiquement, la majeure partie des remarques que tu fais sont liées au fait que je n'explique pas dans le détail la différence entre les threads natifs (ou threads systèmes, ceux liés au processeur et/ou à l'OS) et ceux liés au langage de programmation.

C'est nécessaire pour répondre aux 3/4 de tes questions. Mais ça nécessiterait carrément un cours, ou au moins un article comme celui de Wikipedia.

+0 -0

Je laisse tomber du coup, ça prendrait beaucoup trop de temps d'argumenter sur le pourquoi du comment cet outil est intéressant, ce qu'il apporte de différent etc. Il faudrait passer du temps à expliquer ce que sont les NIO (async IO), ce qu'est un thread natif (ou OS thread) par opposition aux Green threads utilisés dans la majeure partie des frameworks web.

Dommage, mais la tâche est relativement colossale et pourrait/devrait faire l'objet d'un cours complet avant de pouvoir aborder ce qui donne à Node, Undertows, Sinatra, Tornado, Vert.x et consorts leur spécificité.

Merci beaucoup pour vos relectures attentives et conseils.

+0 -0

Je trouve ça dommage que tu ne le publie pas d'autant que on ne peut pas tout ré.expliquer à chaque article. Je ne suis pas persuadé que c'est à ton article d'expliquer ce qu'est la programmation asynchrone et tout ce qui va avec. Ça mériterait un article à part. Beaucoup d'articles déjà publié partent du principe que d'autres paradigmes sont connue, je vois pas pourquoi tu ne pourrai pas faire de même.

J'avoue que j'ai exagéré le rôle de cet article : tu peux te contenter de dire qu'il n'est accessible qu'aux gens baignant dans le domaine de l'asynchrone. Alors, ton article comporterait seulement les spécifités de Vert.x et les nouveautés de la version 3.

Il faudrait que je le relise, en tenant compte de cela.

+0 -0

Je ne pense pas que tu aies exagéré. En tout cas je ne l'espère pas.

C'est juste qu'écrire un truc auquel personne ne pige rien, ça n'a aucun intérêt. Et tes questions me semblent révélatrice de ça : si on ne sait pas ce que l'asynchrone apporte au développement d'application réseau (on en avait parlé sur un sujet à propos du PHP par exemple) en particulier pour les applications web, et quel gain ça représente en termes de scalabilité, l'article n'a quasiment aucun intérêt.

Et la question "mais pourquoi faire un énième serveur web" se posera inévitablement. Alors que toute personne ayant déjà essayé de faire "scaler" un serveur "classique" à grands coups de hardware comprendra sans doute mieux l'intérêt de cette approche.

C'est plus une question de public sur ZdS en réalité.

+0 -0

Je n'ai jamais vraiment pratiqué la programmation asynchrone mais je sais ce que c'est. J'ai non seulement compris ton article mais je l'ai trouvé intéressant et ai apprit des trucs. Je trouve dommage de pas en faire profiter tout le monde mais je peux comprendre.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte