Tags : java8, CompletableFuture

Je vais aujourd’hui vous présenter les CompletableFuture de java 8.

Pour l’exemple, nous allons réaliser un petit programme Java permettant de récupérer le titre le plus long parmi les articles du blog.
Pour faire cela, nous allons récupérer la page archive du blog, pour ensuite récupérer chaque lien d’article et pour finir récupérer le titre des articles.

Méthode naïve

Commençons par la méthode naïve sans java8 :

Cette méthode a l’intérêt d’être très facilement compréhensible, par contre c’est beaucoup trop séquentiel, il faudrait pouvoir exécuter les requêtes en parallel et non de manière séquentiel.

Méthode à base de Future

Nous allons maintenant exécuter les requêtes en parallel à l’aide d’un bon vieux ExecutorService :

Cette méthode est beaucoup plus performante, mais un truc me gène :

boolean allDone = false;
while (!allDone) {
    allDone = true;
    for (Future<String> result : results) {
        if (!result.isDone()) {
            allDone = false;
            break;
        }
    }
    Thread.sleep(50);
}

Avoir du code technique de ce type là en plein milieu, ça me plait pas trop.

Méthode à base de CompletableFuture

Nous allons maintenant transformer notre code pour utiliser les CompletableFuture de java8 :

Personnellement je trouve ce code beaucoup plus lisible et sans (ou très peu de) code technique.

Quelques détails sur l’API :

  • CompletableFuture.supplyAsync : permet d’exécuter un traitement en asynchrone, retourne le CompletableFuture correspondant.
  • CompletableFuture.allOf : Permet de récupérer un CompletableFuture correspondant à la fin de tous les CompletableFuture passés en paramètres.
  • CompletableFuture.thenApply : Execute un fonction une fois le CompletableFuture terminé. Cette fonction prend en paramètre l’objet du CompletableFuture est renvoie un autre type.

Performances

Voici les résultats des trois méthodes en terme de performances :

  • Méthode naïve : 2243ms
  • Méthode à base de Future : 310ms
  • Méthode à base de CompletableFuture : 230ms

Pour les curieux, l’ensemble de ma classe de test se trouve ici.

Commentaires

Tags : blogger, jbake, github

Je vous en ai parlé la semaine dernière dans cet article, je suis passé de blogger à jbake.

Le but de l’article d’aujourd’hui sera de de donner un certain nombre d’astuces autour de cette migration, plus quelques astuces sur jbake.

Mise en place de Jbake

Quand j’ai commencé, je me suis basé sur le post de Cédric, mais j’ai finalement décidé d’abandonner gradle pour passer à mon vieil ami Maven.

La raison de ce changement est assez simple, je connais bien maven :)

J’utilise le plugin jbake-maven-plugin sur lequel j’ai fait deux pull request.
La première pull request est pour qu’il supporte jbake 2.3.0, la deuxième est pour qu’il démarre un serveur livrereload sur le goal inline.

Si ces pull request sont mergées, ou si vous utilisez mon fork, les tests sont plutôt simples, il suffit de lancer :
mvn jbake:inline
Ouvrez ensuite http://localhost:8080, si vous activez livereload, dès que vous faites une modification, un refresh est déclenché, plutôt cool, non?

Concernant la publication sur github, j’utilise le plugin de github : github-site-plugin.

Si vous voulez voir les détails, vous pouvez regarder mon pom.xml.

Migration des articles

Je ne voulais pas réécrire les anciens articles à la main, il a donc fallu que je trouve une procédure automatisée.

Je suis parti du flux rss de blogger, et pour chaque article je crée un fichier html dans mes sources jbake.
Ma classe permettant celà est disponible ici.

Migration des commentaires

Pour la migration des commentaires, j’ai été surpris, ça marche tout seul avec disqus.

Quelques astuces sur les templates

Tags

J’avais commencé avec des templates freemarker, mais j’ai pas réussi à faire ce que je voulais avec.
Je voulais afficher la liste des tags avec entre parenthèses le nombre d’articles possédant ce tag, le tout ordonné par nombre d’articles décroissant.
Je n’ai trouvé aucune solution (sans code java) pour faire ça avec freemarker, alors qu’en groovy c’est relativement simple :

Sitemap des tags

Voici le petit bout de code qui me permet de positionner la date de mise à jour des pages de type tag (correspondant au dernier article sur ce tag) :

Open-source

Pour finir, si vous voyez un truc qui pourrait être amélioré sur le blog, il est maintenent open-source.

Commentaires

Tags : blogger, jbake, github

Vous l’avez surement déjà vu, mon blog a changé de tête…

Si vous voulez voir la différence, allez voir l’ancien blog.

Jbake

J’avais envie de tester jbake qui est un générateur de site statique, un peu à l’image de jekyll mais en java.

J’ai choisi jbake car j’avais envie de pouvoir éditer et tester mon blog de manière offline, et il se trouve que jbake est à la mode actuellement.
Autre avantge, l’article que vous lisez est écrit en Markdown, en voici le contenu.

Hébergement

Vu que je passe sur une technologie avec des fichiers statiques, il est assez simple d’héberger le résultat sur github.

Cédric explique assez bien la marche à suivre sur son blog.

Vous en pensez quoi?

Je ferai un article la semaine prochaine sur les détails de l’implémentation et la migration depuis blogger.
Je vous expliquerai également pouquoi j’ai choisi les templates groovy

En attendant, n’hésitez pas à me dire ce que vous en pensez.

Commentaires

Tags : Assertj, Awaitility, Java, Jetty, SimpleWeb4j, websocket

On a vu comment implémenter des websockets avec SimpleWeb4j dans un précédant article, nous allons maintenant voir comment tester de manière automatisée la partie serveur websocket.


Librairies tierces

Pour garder un code relativement propre, je vais utiliser trois librairies :


Je veux faire quoi comme test?

Je cherche à tester le code du billet précédant qui, pour rappel, était un système de chat. Le serveur de websocket reçoit donc des messages qu'il redistribue à tous les clients connectés.

Scénario de test :

  • Ouverture d'une session 1.
  • Envoi d'un message par la session 1 (message 1).
  • Ouverture d'une session 2.
  • Envoi d'un message par la session 2 (message 2).
  • Envoi d'un message par la session 1 (message 3).
  • Fermeture de la session 1.
  • Envoi d'un message par la session 2 (message 4).
  • Fermeture de la session 2.

Vérifications à faire :

  • La session 1 a reçu 3 messages (les messages 1 à 3)
  • La session 2 a reçu 3 messages (les messages 2 à 4)


Code de test

Assez parler, place au code. J'espère que les commentaires sont suffisants, si ce n'est pas le cas, n'hésitez pas à le dire j'en ajouterais.

Commentaires

Tags : java8, javascript, SimpleWeb4j, websocket

Nous allons voir comment faire du websocket avec SimpleWeb4j.

WebSocket c'est quoi

WebSocket est un protocole permettant la communication de type push entre un browser et un serveur de manière bi-directionnelle.


On fait quoi comme exemple?

Comme je suis super original, on va partir sur un chat (le truc pour discuter, pas l'animal !), ça nous rappellera la grande époque de caramail :)

Pour mettre en place un chat, on a besoin d'un service côté serveur qui peut recevoir des messages en push depuis les clients, et quand il en reçoit un le redistribue à tous les clients.


La partie serveur

Nous allons commencer par créer notre objet métier représentant un message, celui-ci contient l'utilisateur, le texte et la date du message. Il servira pour les messages que l'on envoie aux clients (pour les flux client -> serveur, nous utiliserons une simple String).

Nous allons maintenant créer la route de la websocket avec la méthode SimpleWeb4j.websocket, cette méthode prend en paramètre une String représentant l'url et un WebSocketAdapter. Un WebSocketAdapter et une factory qui contient une méthode prenant en paramètres les "RouteParameters" et qui construit un WebSocketListenner. On a donc le code suivant pour l'instant :

Voyons maintenant comment construire le "WebSocketListener", nous avons pour ça un builder. Nous souhaitons construire un listener en implémentant un comportement sur 3 événements :

  • onConnect : on ajoute la session dans un set pour connaître les sessions ouvertes.
  • onClose : on supprime la session de notre set.
  • onMessage : on envoi le message reçu à tout les clients.
Voici donc le résultat final :


La partie cliente

Pour la partie cliente, on a un objet javascript "WebSocket" qui prend l'url en paramètre du constructeur.

Il nous reste après à définir les callback "onmessage" et "onopen". Pour envoyer un message au serveur, il suffit d'utiliser la méthode WebSocket.send. Si vous voulez plus de détails, vous pouvez aller voir la page de mozilla.

Voici donc la page html complète, comme d'habitude, j'utilise angular.js :) >/p>

Alors, ça vous parait compliqué de faire du WebSocket?

Commentaires


Billets plus anciens disponibles sur la page archive.