Droit à l’oubli du code

Vous n’y avez sans doute pas échappé, Google Code a fermé ses portes. Dommage, j’aimais bien, quand il a démarré, ce service. Et j’y avais quelques projets …

J’aurais pu, pourtant, exporter ses projets pour les mettre dans un quelconque git. Mais je ne l’ai pas fait.

Parce que même si certains de ces projets étaient intéressants (majick-properties, en particulier), je crois qu’il faut savoir certaines choses disparaître dans un oubli relatif (puisque de toute façon, the internet wayback machine se souvient de tout).

Les wikis ont changé, et c’est bien !

Depuis des années, dans les projets auxquels je participais, on utilise des wikis « simples », comme typiquement mediawiki. C’était pratique, mais dès qu’on sortait des pages de texte, on était embêté.
Il fallait alors installer, si on en avait le courage, un logiciel de forum, ou de blog interne, ou tant d’autres choses.Honnêtement, c’était assez peu pratique. Suffisamment, d’ailleurs, pour donner aux utilisateurs peu intéressés comme moi l’impression d’un monde déjà fermé.Et puis j’ai du jeter un oeil, pour différentes raisons, à XWiki (la plus importante étant sans doute l’interview donnée par les patrons de l’entreprise éponyme aux castcodeurs). Et là, le choc :

  • Joli
  • Avec un éditeur WYSIWYG
  • Extensible par une multitude d’applications (forum, gestionnaire de tâches, outil de microblogging, …)
  • Scriptable en Velocity et en Groovy !
  • Installable facilement dans tous les environnements

Bref, une révolution.

Il y a certes deux ou trois choses gênantes, comme le manque de certains imports/exports, mais rien de dramatique à mon sens.

Du coup, forcément, je vais tester plus de choses avec cet outil aussi puissant que bien fichu.

Hier soir … c’était le printemps ?

Parce qu’hier soir, c’était chtijug, chtijug spécial Spring, et Spring boot en particulier

Pour laquelle Brian Clozel a fait un gros boulot de livecoding.

Alors Spring Boot, qu’est-ce que c’est ?

Eh bien c’est tout ça

D’après ce que j’ai compris, c’est une façon pour les gens de Spring de simplifier la vie des développeurs en fournissant

  1. Une façon très chouette de bootstrapper une application à partir de leur site web.
  2. Un framework d’utilisation de l’ensemble des couches Spring, qui inclut évidement le code, mais aussi les bonne spratiques d’utilisation
  3. Une interface « simplifiant » l’utilisation des autres bibliothèques de Spring.

En revanche, Spring Boot n’est pas une version simplifiée de Spring (tout Spring peut être utilisé dans Boot), ni un outil à réserver aux POC.

Donc, brian nous a fait du live-coding. Et sans utiliser cette cochonnerie de thème sombre illisible. Et ça c’est bien.

On a donc pu voir en action

  • Spring-data-mongo
  • Spring-rest (je reviendrai plus bas là-dessus)
  • Spring-security

Et quelques autres.

Au passage, j’ai beaucoup apprécié la façon d’utiliser les TODO de Brian, qui lui permettait de dérouler dans un ordre sympatoche les différents éléments de sa démo.

Il a ensuite fait une rapide présentation des différentes nouveautés de Spring 4.1 (en oubliant de préciser que certaines ne fonctionnent qu’avec java 8, comme par exemple les injections de types paramétrés).

Sauf que …

Comme le dit fort bien Thibaud

Pour clarifier un peu … J’ai fait du Spring il y a maintenant 8 ans. A l’époque, on était en plein XML hell, et Spring en était le champion. Des fichiers XML partout, avec des beans à câbler dans tous les coins, c’était l’enfer. Et je me souviens en particulier à l’époque d’un aspect pénible de Spring, qui était le fait de devoir toujours passer par la doc pour obtenir des infos : rien n’était découvrable automagiquement dans l’IDE.

Aujourd’hui, le XML Hell a été remplacé par l’annotation hell. Et honnêtement, ça ne change rien au problème : on ne sait toujours pas quel bean vient de quel endroit, et qui est injecté où.

Vous serez tenté de me dire que c’est exactement pareil dans le JavaEE d’en face, et vous aurez raison. Cependant, dans le monde JavaEE, j’ai l’impression qu’il existe une distinction plus claire entre les différents types de composants : les EJBs, les beans sont plus facilement définis, et mieux isolés. Enfin, je trouve.

Spring-data a tout copié sur gaedo ?

Quoi ? Vous ne connaissez pas gaedo , La meilleure librairie de mapping objet/stockage en Java ?

Je n’ai pas pu m’empêcher d’y penser quand j’ai vu cet écran

IMG_20150203_192539

Que vous pouvez comparer avec la doc de gaedo sur les finders dynamiques… Ouaip, c’est pareil. Et ouaip, on a tous copiés sur Ruby on Rails.

Oui mais Spring boot, c’est léger ?

Comparez par exemple avec DropWizard (comme l’a fait JavaLobby), à Wisdom ou à ninja … Dans tous les cas, Spring boot apporte effectivement la légereté de ces outils en s’appuyant sur la force de Spring. Mais du coup, c’est loin d’être aussi léger que ce que vous croyez : mettre en place un stockage va impliquer l’utilisation de Spring-data-*, qui va vous tirer des tonnes de dépendances, et il en sera de même pour implémente rune API REST : vous passerez par la librairie idoine du portfolio Spring à travers une couche d’adaptation, et du coup ce ce sera encore une fois un gros paquet de dépendances, et une complexité pas forcément masquée.

Conclusion

Donc une session intérressante, sur un des frameworks majeurs du monde Java, mais qui n’en était pas pour autant exaltante. Et c’est bien normal : Spring est une solution mature, déployée à des échelles industrielles, et dans des environnements qui n’ont rien de glamour. Ils ne cherchent donc pas à épater les utilisateurs, mais plutôt à trouver une solution qui marche, et qui réponde sérieusement aux problèmes des applications d’aujourd’hui.

Français, vous me dégoûtez

J’espère que le titre est assez clair.

Après les attentats du début du mois, j’ai cherché désespérément comment écrire que, comme d’autres, je n’étais pas Charlie.

Hélas, je n’ai pas trouvé.

Mais aujourd’hui, ma colère contre cette récupération idéologique est … incandescente.

Parce qu’il n’a pas suffit de commémorer la liberté d’insulter … pardon, d’expression, en invitant un ramassis d’amis de cette liberté (du moment que les opinions leur plaisent, évidement).

Il n’a pas suffit non plus de commémorer cette même liberté de haïr … pardon, d’exprimer la franchouillardise, en remettant des militaires dans la rue. Au passage, je ne résiste pas à deux appartés à ce sujet.

Vous savez que les militaires disposent d’armes incomparablement plus dangereuses que les flics ou les gendarmes ? Mais est-ce que vous connaissez les différentes règles d’engagement ? Pour ce que j’en sais, ça me terrifie. Parce qu’un militaire peut ouvrir le feu bien plus facilement qu’un policier. Et qu’un FAMAS a une portée incroyablement plus grande qu’un pistolet, fût-il automatique.

En bonus, je sais pas vous, mais moi, personnellement, voir un plan de défense relevé après l’attaque, ça me paraît aussi utile qu’une capote enfilée après l’éjaculation …

Bref, revenons à notre sujet pas joyeux.

La liberté d’expression a donc été défendue en invitant ses pires détracteurs, en mettant en place une politique visible d’intimidation des citoyens. Et c’est tout ?

Non. C’est encore pire.

La liberté d’expression a été défendue en punissant pénalement des enfants qui s’expriment.

Lisez donc ces deux articles

Et maintenant, essayez de vous regarder dans un miroir. Personnellement, j’ai beaucoup de mal à croire vivre dans un pays qui respecte la liberté quand je lis ça.

Et plus encore quand je vois les hommes politiques de mon pays se satisfaire de marquer des enfants à vie.

Quand je vois ça, je pleure.

Et c’est encore pire quand je compare la réaction française (raciste, hypocrite, mesquine) aux réactions d’autres pays, où la fraternité avait du sens.

Honnêtement, j’ai rarement eu autant envie de quitter ce pays qui sent le rance qu’en ce moment. Et ce qui provoque ce dégoût, ce ne sont pas quelques terroriste imbéciles, mais tous les carriéristes amateurs de dictature beige. Et oui, c’est peut-être, de ma part, une réaction allergique à la réaction allergique de notre pays que mentionne Maître Eolas.

Une étincelle au chtijug

Et c’est reparti pour un tour, cette fois-ci sur du Big Data, je crois …

J’avais entendu parler de Spark dans l’interview de Sam Bessalah chez les castcodeurs, et Duy Hai Doan est venu préciser les idées.

Et Duy Hai a été sympa pour rendre les slides disponibles sur le web

Ainsi que sa présentation pour Spark avec Cassandra

En nous expliquant d’abord que Spark est bien plus concis que Hadoop (en partie parce qu’en Scala), et bien plus rapide (parce que stockant ses données en mémoire, plutôt que sur disque, comme Hadoop). En bonus, Spark traite les données en graphe (d’ailleurs, de façon amusante, Blueprints n’est pas listée dans les API de graphe Big Data), en SQL, ou via des flux.

Cool, non ?
Petit détour par les RDD, qui reprennent, conceptuellement, ce que toute personne ayant implémenté un processeur de requête comprendra : il n’interprète les requêtes qu’au dernier moment. Par exemple, un filter suivi par un groupBy ne sera évalué que si, à la fin, l’utilisateur du RDD tente de récupérer, d’une façon ou d’une autre, les données sur son poste. D’une façon intéressante, certaines opérations vont redistribuer les données sur le réseau (typiquement, un groupBy) à cause de notions compliquées de « hashcode » de données. D’ailleurs, curieusement, on ne distingue pas les opérateurs impliquant un brassage (groupBy) des autres, ni d’ailleurs des actions démarrant le processus. Et personnellement, je trouve ça moche pour une raison bien simple : le développeur peut (et va) écrire du code inefficace, simplement parce qu’il ne saura pas comment distinguer le code efficace du code inefficace.
On passe ensuite aux API.

Spark supporte le SQL, le streaming, et le mapping d’objets. Pas mal … Sauf bien sûr qu’il y a toujours ces histoires de redistributions de données temporaires, que je vois come le vrai défaut de Spark. Je m’explique …

Comme les opérations brassant les données peuvent les envoyer n’importe où, si on en écrit « par accident », on risque de passer d’un code très rapide (parce qu’en mémoire) par un code très lent (parce que sur le réseau). Et Spark ne fournit aucun moyen de distinguer les deux, malheureusement.

Et ça empire si on utilise Cassandra comme couche de stockage, à cause de la nature multi-datacenter de l’outil, qui va certes permettre de survivre à des accidents nucléaires, au prix de coûts de transferts de données.

Pour troller, Spark, c’est bien, pour faire du SQL distribué.

Ré-réinstaller fonz_fun_plug

Parce que j’ai rebooté mon NAS, et depuis, j’ai perdu

  • l’accès SSH
  • Lighttpd
  • minidlna

Heureusement, je peux toujours y accéder en « vrai » FTP et consulter le ffp.log qui me dit des choses aussi absconses que

* /ffp/start/uwcron.sh ...
wc: can't resolve symbol 'posix_fadvise64'

ou

* /ffp/start/sshd.sh ...

/ffp/bin/ssh-keygen: symbol '_res': can't resolve symbol

/ffp/bin/ssh-keygen: symbol '__stack_chk_guard': can't resolve symbol
tr: can't resolve symbol 'posix_fadvise64'
Starting /ffp/sbin/sshd 

/ffp/sbin/sshd: symbol '__stack_chk_guard': can't resolve symbol
* /ffp/start/rsyncd.sh inactive

Préferrant la brutalité à la subtilité, je vais donc réinstaller fonz_fun_plug 0.7. Heureusement que j’ai déja détaillé les étapes.

Donc allons-y …

(je démarre à 11H00)

Au passage, je lis dans mon article de référence

You may select to upgrade system package by packages from other repositories, but it may bring some system instability. Do it at your own risk …

Ouais, ben j’aurais dû le mettre dans une espèce de welocme message …

(et à 11H22, ffp est réinstallé, et je redémarre pour vérifier que les modifs fonctionnent – et oui, ça marche).

Par contre, dans la partie

Installer ensuite toutes les libs de minidlna, puis minidlna

Bêtement, je n’ai pas noté la liste des « libs de minidlna » … heureusement, une rapide recherche sur « kylek minidlna » me donne cette liste :

  • libjpeg-8c (system)
  • flac (kylek)
  • ogg (kylek)
  • vorbis (kylek)
  • libid3tag-0.15.1b (kylek)
  • sqlite-3.7.9 (system)
  • libexif-0.6.2 (system)

Et ça ira !

Avec ça, minidlna redémarre correctement.

J’ai en revanche un petit souçi avec lighttpd … mais je vais arranger ça rapidement …

Donc, si après le démarrage de lighttpd, je ne vois rien dans mon navigateur internet, je dois aller jeter un oeil dans /mnt/HD_b2/www/logs/error.log pour y trouver des erreurs comme par exemple

2015-01-10 18:36:22: (mod_fastcgi.c.1103) the fastcgi-backend /ffp/bin/php-cgi failed to start:
2015-01-10 18:36:22: (mod_fastcgi.c.1107) child exited with status 16 /ffp/bin/php-cgi
2015-01-10 18:36:22: (mod_fastcgi.c.1110) If you're trying to run your app as a FastCGI backend, make sure you're using the FastCGI-enabled version.
If this is PHP on Gentoo, add 'fastcgi' to the USE flags.
2015-01-10 18:36:22: (mod_fastcgi.c.1397) [ERROR]: spawning fcgi failed.

Et donc, je n’ai pas dû installer la bonne version de PHP …

Bon, en fait, c’est pas ça : quand je tape php -v, j’obtiens ça

php: can't load library 'libcurl.so.4'

Normal, puisque curl n’est pas installé.

Donc il faut installer curl avant de tenter d’utiliser du php !

J’ai donc maintenant un lighttpd+php qui marche à peu près (suffisament en tout cas pour jtartQage). En revanche, pour krissfeed ou Shaarli, j’ai toujours des erreurs

Fatal error: Call to undefined function gzinflate() in /mnt/HD_b2/www/pages/Shaarli/index.php on line 773

Qui sont liées, d’après internet à … des problèmes curieux de zlib (que j’ai pourtant installée).

Bon, en fait non, c’est juste parce qu’il ne faut pas oublier de copier le php.ini qui est sauvegardé sur GitHub !

Cinq ans d’ALM, putain !

Encore une suite à cinq ans, putain !

Oui, je mets le terme ALM à toutes les sauces, parce que c’est mon bon plaisir.

Donc, sur ce gros projet, j’ai fait ce qu’on pourrait de l’ALM. Qu’est-ce que je mets sous ce terme ?

L’ensemble des tâches qui permettent de passer du code au produit.

Ca inclut, de façon non exhaustive

  • Les outils de build
  • Les outils d’intégration continue
  • L’intégration entre ces outils et les outils de suivi de bugs.

Et évidement, je vais vous (re)parler de Tuleap.

Mais avant, je vais reprendre les étages un par un

Compiling !

Aimablement fourni par http://xkcd.com/303/ mais vous vous en doutiez, non ?

Quand on a commencé notre projet, j’avais déja touché du build maven multi-module. Maias je n’imaginais pas que j’en ferais autant, puisque notre build intègre maintenant

  • De la compilation flex avec flexmojos (raisonnablement facile)
  • De la compilation C++ … et selon la plateforme, cette compilation utilise soit Visual Studio, soit XCode … alors ne me parlez pas de maven-nar-plugin, parce qu’il est notoirement insuffisant pour nos besoins.
  • Du packaging sous d’innombrables formes (war, ear, zxp, …)

Qu’est-ce que ça m’a appris ?

It’s alive

Que la vraie force de maven n’est pas la création d’un format de dépendance universellement utilisé.

Je veux dire, c’est vrai que c’est pratique, ces dépendances, mais quand on arrive à du build « d’entreprise », c’est-à-dire moche et farci de profils, la vraie force de maven, ça n’est pas ça. Non.

La vraie force de maven, c’est de définir un cycle de vie universel. Parce que ce cycle de vie permet, quelquesoit le type de projet, le langage utilisé, ou quelque concept que ce soit, de positionner les différentes opérations dans un tout cohérent. Ca n’a l’air de rien, comme ça, mais c’est réellement indispensable pour les gens qui s’occupent de faire un packaging réaliste. Parce que je sais, quand j’en arrive à la phase « packaging », que tout mon code est compilé, testé, que les ressources ont été traité.

Franchement, quand je regarde les alternatives à maven, je me dis qu’ils n’ont rien compris : ne pas reprendre ce cycle de vie, c’est juste irresponsable maintenant.

Groovy, baby

Alors évidement, vous me direz qu’écrire un plugin maven pour les cas non standard, c’est l’enfer. Et c’est vrai.

Heureusement, j’ai également découvert une gradation dans la personnalisation que j’applique de façon systématique (vous savez, pour tous ces trucs foireux – comme par exemple construire un fiochier de config requirejs à partir de dépendances Javascript) :

  1. Je trouve un plugin maven qui convient ? C’est la fête
  2. Je trouve un ensemble de tâche ANT qui colle ? Cool
  3. Je peux écrire un script groovy avec gmaven ? Bien (dans ce cas-là, n’écrivez pas le script dans le build, mais mettez-le dans un dossier clairement séparé, par exemple src/build/gmaven)
  4. Aucun des trois n’est suffisant ? Alors il est temps d’écrire un plugin maven.

Avec ça, rien n’est impossible dans un build.

Et notez que je ne suis passé du point 3 au point 4 que dans deux cas. Et dans les deux cas, c’est parce que je devais en fait écrire un plugin avec cycle de vie complet. Dans tous les autres cas, groovy a été suffisant, et je dirais même fun.

Non mais tout ce XML, quand même …

Tout ce XML de maven ? A priori, on le regardait sous tes les angles dans m2e quand on ajoutait un nouveau type de build, et après, il n’y avait plus vraiment besoin d’intervenir dessus. Alors dire que c’est pénible, faut pas déconner. Le pire, en fait,a vec maven, c’est qu’Eclipse ne différencie pas les scopes des dépendances. Heureusement pour nous, Jenkins compilait en-dehors de tout IDE.

Make me a sandwich

Et encore, on n’a pas besoin de sudoer Jenkins

Ben oui, Jenkins, le gagnant de la grande guerre du fork.

Lui aussi, on l’a bien tanné.

Justement à cause de notre build natif multi-plateforme. Parce que si on compile une partie de notre application selon la plateforme, on fait comment pour avoir les artefacts dans un build commun ?

Eh bien on se fait un profil spécial Jenkins, dans lequel le build maven est découpé en parties multi-plateformes et dépendant de la palteforme, et on joue du build matrix plugin pour que tout compile et se package sans problème.

Et ça marche, mpême si c’est pas très facile.

Ca chauffe !

A vrai dire, le plus grand échec a été l’implication de l’équipe : même avec un bon radiateur, personne (sauf la testeuse en chef – que toujours elle marche sur un chemin de roses fraîchement coupées) ne s’y est jamais vraiment intéressé. Et ça, c’est triste.

Parce que ça veut dire que cette histoire d’intégration continue n’a été qu’une lubie de ma part, et que je n’ai pas réussi à en communiquer la valeur pour l’équipe, le projet, le produit.

Là-dessus, je peux dire que je retiens la leçon, et que je ferais en sorte que les builds en échec ne puissent plus être ignorés.

Tester c’est douter

Cela dit, tout n’est pas si sombre, puisque le projet a quand même une bonne partie de son code testé, et que TDD a été utilisé dans la plupart des acceptations du terme. La meilleure, et la plus efficace étant qu’aucun bug ne devait être marqué corrigé sans qu’un test ait été ajouté spécifiquement. Parce que

ce qui a foiré foirera

Ca a l’air con dit comme ça, mais ça c’est vérifié à chaque fois : les parties de code ayant connu un bug en ont toujours connu plus, et plus encore.

Heureusement qu’il n’y avait pas d’exploitation statistique des liens entre code et bugs pour vérifier ça, sinon c’aurait été l’enfer.

Et mylyn ? Et Tuleap ?

Là, par contre, l’échec est patent.

Plus encore quand je regarde ce que j’ai pu faire avec gaedo où, là, chaque bug est corrigé à travers un commentaire de commit.

Imaginez que le seul lien dont on ait pu dispoiser était, éventuellement, un lien HTTP dans un commentaire de commit référençant un bug. Comme ça, par exemple :

http://mantis/bugs/view.php?id=7137
the error was stupid : I did not add children to parents when they were needed

ca, c’est moi qui l’ait écrit aujourd’hui.

Ce qui est bizarre, c’est que j’avais parlé de mylyn, de Tuleap, et qu’un autre collègue avait parlé de svn commit hooks … mais aucune de ces tentatives n’a pris. Et pour des raisons diverses … La pire étant celle qui nous a empêché d’utiliser Tuleap : « j’ai pas vraiment eu le temps de regarder ». je dois dire que ça, ça m’a tué.

Alors, content ?

En fait, la plupart des choses installées vont continuer à fonctionner … jusqu’à ce qu’on les arrête.

En revanche, je reste convaincu de l’intérêt de ces outils, et je n’hésiterai pas à pousser leur adoption la prochaine fois.

Cinq ans de projet, putain !

TL-DR

Dans une série d’article commençant par cinq ans, putain ! j’essaye de faire un post-mortem d’un projet d’environ 5 ans de dév. Là, je vais vous parler gestion de projet. Ca n’est peut-être pas mon rôle, mais j’y ai trempé un peu.

Ouaip, bosser sur le même projet pendant cinq ans, c’est long.

Quand on a commencé ce fichu projet, on s’est dit que ce serait bien de faire de l’agile plutôt que du n’importe quoi, comme c’était auparavant l’usage dans la boîte.

Du n’importe quoi ?

Oui : sur la première année, j’ai aidé mes collègues à finir de livrer une version du logiciel historique dont la date de livraison initiale était … avant mon arrivée dans l’entreprise. Et en fait, il a fallu toute la première année pour livrer.

Et encore, on a gagné du temps en

  • mentant pendant les comités de pilotage
  • virant la moitié des fonctionnalités
  • introduisant des gros hacks pour que ça marche

Est-ce que c’était intellectuellement satisfaisant ? Bien sûr que non. Surtout que de l’agile qui marche, j’ai déja vu ça il y a bien des années. J’étais donc plutôt déterminé à assister mon mentor local dans cette transition.

Allez on commence les assouplissements

La première chose qu’on a mis en place, curieusement, c’est un pipeline d’intégration continue. Et ça a bien marché. Parce que ça nous permettait de ne plus stresser (trop) autour des livraisons. Bien sûr, des gros paquets de code foireux ont été livrés, et des retards conséquents ont été pris. Mais le fait de disposer chaque jour d’un build complet était (et est toujours) une satisfaction profonde, parce que ça donne une existence « concrète » au produit qu’on développe.

Et puis il a fallu s’intéresser à l’amont. Les user stories, les tâches, les sprints et toute cette terminologie que je trouve rétrospectivement inutile et qui n’a en fait pas marché. Je vais essayer d’éclaircir.

Donc, on a essayé de faire du scrum (qui comme chacun le sait, est une forme d’agilité) et, à cause de notre équipe moitié intégrée, moitié distribuée, on a dû gérer nos tableaux avec un outil (qui n’est pas en cause ici).

Raconte-moi une histoire – le backlog et les stories

Evidement, dans ces tableaux, la première entrée, c’est le backlog, et dans ce backlog, on trouve les stories de notre client (en l’occurence, le marketting). Et c’est là qu’est le premier problème : faire du marketting, et réussir à exprimer un besoin, c’est loin d’être simple. Et les personnes qui s’en sont occupées n’ont sans doute pas été formées à cette tâche (mais ça, ça reviendra souvent). Du coup, on a pu rencontrer, malgré le formalisme assez classique « En tant que …, Pour …, Je voudrais .. » des problèmes assez pénibles :

  • Toutes nos stories avaient comme rôle « l’utilisateur ». Du coup, impossible de dégager différents sous-sytèmes ou autorisations qui auraient pu clarifier les choses. En fait, il a fallu attendre que le projet ait déja 4 ans pour voir émerger différents rôles.
  • Il n’y avait que rarement des demandes, et bien plus souvent des solutions … dont le réalisme prétait évidement le flan à la critique.
  • Il était également  courant de voir le contenu du backlog totallement transformé d’un sprint au suivant, essentiellement parce que le marketting avait rencontré un client avec d’autres besoins

Des défauts pénibles, donc, que je regrette vraiment de ne pas avoir tenté de corriger, d’une façon ou d’une autre.

Qu’est-ce qu’il aurait fallu améliorer ?

Notre marketting n’a jamais compris ces histoires d’agilité : pour eux, il fallait « juste livrer ». Du coup, leur expliquer que donner des rôle bien définies était difficile. Pour ça, je pense que l’approche des personaes aurait été bien pratique : mettre un nom, un visage, pour que,v raiment, les différents rôles apparaissent clairement.

De la même manière, la fourniture de solutions complètes (mais toujours incorrectes) aurait sans doute nécessité de notre part plus d’accompagnement initial, pour vraiment comprendre le besoin sous-jacent plutôt que l’implémentation proposée.

Il est chouette, ton jouet … il fait quoi ?

Cela dit, on disposait de nos stories, qu’on traduisait en paquets d’items, ce qui nous paraissait correct, jusqu’à la première fin d’itération.

Oh, oui, pardon, je parle d’itération … sans doute parce que nos sprints avaient dépassé les 6 mois, ce qui les rend assez … peu courts, dirais-je.

Et donc, à la fin d’une itération, on fait deux choses :

  1. une démonstration
  2. une rétrospective

Deux occasions d’être fier de son travail … ou pas.

Ca tourne !

La démonstration … l’occasion pour l’équipe de briller devant le marketting. Qu’est-ce qui pourrait foirer ?

Oh, plein de choses (que j’ai vu, hein)

  1. Des développeurs qui ne préparent pas de démonstration, et ne s’attendent même pas à en faire, alors que leur développement est releasé
  2. Des démos qui foirent
  3. Un marketting qui profite de la réunion pour parler d’autres parties de l’application (qui n’ont reçues aucun développement, donc)
  4. Un autre marketting qui profite lui aussi de cette réunion pour râler sur cette équipe de dév qui est toujours en retard

Et quand je dis que je les ai vues, je veux dire que je les ai toutes vues dans la même démo. Alors forcément, à la fin de la démo, l’équipe est … peu satisfaite, pour dire le moins.

Qu’est-ce qu’il aurait fallu améliorer ?

La préparation de la démo, évidement. Il aurait fallu demander à toute l’équipe si les démos étaient prêtes, et testées. Et j’insiste d’autant plus sur le second point que j’ai moi-même foiré une démo parce que je l’avais insuffisament testée. Pour le premier point, je dois bien avouer que la seule façon de s’assurer que les gens préparent une démo est de les laisser se vautrer sur scène au moins une fois.

Pour le marketting, là, c’est simple, parce que je l’ai fait la fois suivante : il ya  un ordre du jour clair à cette réunion, et si certains veulent s’en écarter, c’est à l’animateur d ela réunion (moi, sur ce coup-là) de les recadrer, ce que j’ai fait.

Et dans les coulisses

Parce qu’il y a un pendant interne à cette démo : la rétrospective.

Personnellement, j’adore ce moment où on peut tenter de proposer de nouveaux modes d’organisations.

Par exemple, c’est lors d’une de ces réunions que j’avais proposé qu’on utilise Tuleap … mais j’en reparlerais.

Bref, là aussi, c’est une réunion qu’il vaut mieux préparer …

Et comme vous devez vous y attendre, j’ai eu quelques réponses comiques aux trois questions rituelles.

Vous savez :

  1. Qu’est-ce qui a bien marché ?
  2. Qu’est-ce qui n’a pas bien marché ?
  3. Qu’est-ce qu’on peut améliorer ?

Et l’ordre est important : commencer par ce qui a bien marché permet normalement aux gens d’avoir un étatt d’esprit positif … enfin, normalement.

Mais avant d’en venir aux insultes internes, une petite astuce offerte

Tout ça, c’est la faute à Raoul.

Lors de la rétropsective, regardez bien la deuxième question : c’est la porte ouverte aux réglements de compte. Pour les éviter, l’astuce est simple, on avait une persona de mauvais développeur : Raoul Abdaloff (le nom ne doit rien au hasard, et tout à l’UMP). Et tout ce qui s’est mal passé est de sa faute. Une fois muni de ce mauvais développeur, qu’est-ce qui peut foirer ?

Tout va mal, et rien ne s’améliorera

Dans l’ensemble, ces réunions se passaient bien. Jusqu’à ce jour funeste, où trois collègues ont répondu dans un bel ensemble

Qu’est-ce qui a bien marché ?

Je sais pas

Qu’est-ce qui n’a pas bien marché ?

Tout

Qu’est-ce qu’on peut améliorer ?

Rien

Là, faut être lucide, parce que les mecs, j’ai bien eu envie de les passer par la fenêtre.

Qu’est-ce qu’il aurait fallu améliorer ?

Pour la rétropsective, pas grand chose, puisque le but du jeu était d’améliorer le processus. Et ça marchait bien !

Du coup au bout de cinq ans c’est le top ?

J’ai déja parlé du dépôt de bilan, non ?

Eh bien on peut dire que ça a tout détruit.

Aujourd’hui, il n’y a plus

  • de démos
  • de rétrospectives
  • de sprints
  • d’agilité
  • d’envie

Ca calme, non ?

Mais pourquoi ?

Au fond, l’agilité, le scrum, le lean, le kanban, tout ça, c’est mignon, mais c’est juste un mensonge.

Parce qu’en fait, ces idées se contentent de dire qu’il faut que les personnes aient envie d’améliorer leur mode de travail pour que leur mode de travail s’améliore … Autrement dit, ça permet plus de canaliser l’enthousiasme de jeunes chiens fous que de remotiver des vieux développeurs dont la culture sectaire a réduit l’enthousiasme a néant.

Et, je regrette de le dire, même mon enthousiasme a disparu dans la bataille (d’un autre côté, c’est aussi pour ça que je m’en vais).

Du coup, si je peux me permettre un conseil aux apprentis agilistes, ou à ceux qui se demandent pourquoi leur processus agile est arrêté au bord de la route : regardez vos développeurs, et vos « clients ». Est-ce qu’ils sont motivés ? Est-ce que ça leur plaît ? Est-ce qu’ils ont envie de faire mieux ? Si ça n’est pas le cas, laissez tomber tout ça, et contentez vous de faire des itérations courtes, et de durée fixe. Parce que ça, le rythme, ça aide aussi beaucoup. Et le perdre, souvent, c’est un signe que quelque chose d’autre ne va vraiment pas.

 

Ch’mongoDB

Eh ouais, hier soir, c’était chtijug sur MongoDB avec Tugdual Grall.

Mais avant, minute copinage …

Le chtijug a la chance d’avoir un nouveau sponsor, et ça, c’est cool (d’autant plus que ce sont mes voisins de bureau jusqu’à ce soir) :

IMG_20141217_185256[1]

Le représentant d’Onyme a peut-être un moins chouette polo que certains précédents sponsors, mais un sacrément chouette discours

Et je me suis laissé dire qu’ils recrutaient

Bref, merci les gens !

Revenons-en donc à Tugdual

IMG_20141217_185548[1]

Oracle, eXo, Couchbase, MongoDB … clairement, le développeur un peu âgé a souvent touché à plein de trucs

Même fatigué, c’est un speaker sacrément rodé qui nous a fait une présentation intéressante, bourrée de live-coding, sur MongoDB.

Alors MongoDB, qu’est-ce que c’est ?

IMG_20141217_190640[1]

Mongo, une base agile, flexible, intituive et stockant les données dans un format facile à exploiter

En gros, c’est une espèce de gros système de stockage de BSON (un format binaire adaptant le JSON) disposant d’interfaces dans les différents langages … mais ça n’est pas ce que racontait vraiment ce slide moche.

Non. Ce que voulait expliquer Tugdual, c’est que les bases de données relationelles datent de 40 ans, à une époque où l’esapce disque coûtait vraiment cher. Et donc à cette époque, l’optimisation la plus importante concernait l’utilisation du disque. D’où les bases relationenlles où la donnée est forcément unique, et en troisième forme normale.

C’est pratique pour les DBA, parce que la donnée est bien structurée.

C’est en revanche infernal pour le développeur, puisque la donnée n’est pas accessible facilement. Ce qui explique, par exemple, l’intérêt pour les outils de mapping objet-relationnel.

Un autre inconvénient du fait qu’une écriture se fasse à de multiples endroits, c’est que l’écriture nécessite d’être encapsulée dans une transaction, qui est lourde en termes de ressources pour le serveur (et donc impactant l’ensemble des clients).

A l’opposé, MongoDB cherche à être une base de stockage agréable pour les développeurs.

Ca veut dire quoi ?

  • MongoDB stocke des documents en JSON, qui peuvent contenir des champs simples ou des tableaux de tableaux de tableaux (avec toutefois des limites … qui me semblent assez difficiles à atteindre à première vue).
  • Si deux documents doivent contenir chacun la même donnée, il peut être plus simple de dupliquer cette donnée … ou de la référencer (mais dans ce cas, c’est le développeur qui gèrera l’unicité du lien)
  • Du coup, comme le document est complet, il n’y a pas vraiment besoin de transactions : soit il est écrit, soit il ne l’est pas, mais le développeur le sait tout de suite. Donc MongoDB est non transactionnel, et ça n’est pas grave.

Et paf, Tugdual enchaîne sur une démonstration de la « convivialité » du shell mongo.

insertion d'un document dans la collection "customers", et récupération de la liste des "customers"

insertion d’un document dans la collection « customers », et récupération de la liste des « customers »

Et là, c’est le drame : comme le shell Mongo n’offre ni complétion, ni mise en valeur de la syntaxe, et que Tugdual était un peu fatigué (mais ça, je comprends, parce que coder à l’heure de l’apéro, c’est loin d’être facile), les accolades oubliées s’enchaînent en rafale

Ami lecteur, trouve l'accolade manquante ... Ouaip, c'est lioin d'être facile

Ami lecteur, trouve l’accolade manquante … Ouaip, c’est lioin d’être facile

Notez que je ne critique pas Tugdual, mais le shell mongo. Peut-être qu’un outil comme Robomongo, mongodb-shell ou même l’un des innombrables plugins Eclipse aurait pu lui faciliter la vie. Mais je comprend qu’en tant qu’évangéliste Mongo, ça lui soit un peu difficile d’utiliser des outils tiers.

Bref. Après l’insertion, une autre chose intéressante : la seule chose que doivent avoir les documents Mongo, c’est un attribut « _id » qui peut être soit généré (à partir de l’adresse Mac, du numéro de process, et du timestamp unix), soit écrit manuellement. Et il se passe quoi quand un utilisateur essayé de créer un nouveau document avec un _id déja utilisé ?

Si j'essaye d'avoir deux documents avec le même _id, j'ai droit à une jolie erreur

Si j’essaye d’avoir deux documents avec le même _id, j’ai droit à une jolie erreur

Bon, maintenant que j’ai bourré la base, il est temps d’y chercher des trucs.

Et là, franchement, pour moi, c’est le moment du malaise.

Parce qu’autant je veux bien comprendre l’intérêt des documents en JSOn, des réponses du serveur en JSON mais quand Tugdual a fait ses query/update avec du JSON pour

  • rechercher les documents à mettre à jour
  • définir les opérations d’altération à effectuer (modification, suppression, insertion)

Je dois avouer que j’ai eu comme un malaise

Regardez donc :

Une opération simple de recherche et mise à jour, avec un paquet de JSON dedans

Une opération simple de recherche et mise à jour, avec un paquet de JSON dedans

Et si ça ne vous paraît pas assez clair il y a évidement de la doc sur internet.

Je vais quand même essayer de clarifier mon malaise : il me semble que tous les paramètres de toutes les opérations sur une base MongoDB sont passés sous forme de JSON. Et c’est quelque part assez bien.

Toutefois, tenter d’exprimer une recherche et une mise à jour sous cette forme paraît assez bizarre, surtout vu quelques choix faits (et présentés ici)

  • Les opérations de MongoDB sont définis dans les paramètres sous forme d’attributs JSON préfixés par « $ » alors n’allez pas utiliser ce caractère magique dans vos données !
  • Si vous cherchez au fond d’un sous-document, il faudra passer votre chemin de recherche dans une chaîne (parce que « . » n’est pas accepté comme clé dans un hash JSON). Du coup vous aurez certaines clés avec des guillemets autour et d’autres sans. Et vous vous demanderez d’où vient l’inconsistence.
  • Si vous cherchez dans un tableau une valeur ayant plusieurs propriétés, ce sera … un peu plus compliqué.

Bref, je peux le reconnaître, je n’ai pas aimé cette syntaxe, bien qu’elle soit extrêmement déclarative.

Bon, une fois arrivés là, il est temps de sortir du shell et de passer au driver Java, qui se présente sous plusieurs formes (au passage, il y a des tonnes de drivers, listés dans une très belle page – dixit Tugdual) :

  • Un driver basique qui vous fait manipuler des DBObject qui sont en fait une vision javaisée et fluente des documents JSON. Au apssage, ce driver fournit un chouette outil de création de requête : QueryBuilder.
  • Morphia, qui est un ODM qu’on pourrait considérer comme un concurrent d’Hibernate OGM ou de Spring Data, mais spécifiquement conçu pour MongoDB.
  • MongoJack qui utilise les annotations de Jackson pour mapper les objets Java sur les documents JSON.

Petite parenthèse : le style Dracula d’Intellij ne m’a paru super lisible …

Et pourtant j'étais au deuxième rang ...

Et pourtant j’étais au deuxième rang …

Une fois ces différents outils présentés, Tugdual nous explique, à travers un exemple d’application web, comment utiliser tout ça au mieux.

D’après lui, et plus j’y pense, plus j’approuve, la meilleure solution et d’utiliser le driver basique pour les lectures, et les mappers pour les écritures. Et la raison est assez simple :

En lecture, on passe le JSON de Mongo jusqu’au client … typiquement écrit en Javascript, et donc parfaitement capable de lire ce Javascript.

En revanche, en écriture, pour contrôler ce qui est écrit dans la base, on a intérêt à passer par un mapper. MongoJack a ma préférence … surtout que, contrairement à Tugdual, je sais lui faire ignorer les propriétés inconnues (en utilisant par exemple la DeserializationConfig).

Une fois ce tour du dev fait, Tug est passé au clustering … Bon, là, c’est assez classique : il y a du sharding, de la haute disponibilité via l’élection automatique d’un master … La routine, en quelque sorte.

Et il était déja l’heure du …

Ouaip, Onyme sait toujours aussi bien recevoir !

Et alors, est-ce que je vais passer à MongoDB ?

Bon, j’ai failli il y a peu travailler sur une application utilisant massivement du MDM. Et MongoDB faisait partie des systèmes de stockage candidats.

Je dois bien reconnaître que cette présentation m’a appris pas mal de choses vraiment chouettes sur cette base. Et je comprend bien les cas d’utilisation présentés par Tugdual :

  • Vision 360° d’un client pour, par exemple, du support
  • Aggrégation de données provenant de façon assynchrone de plusieurs systèmes de gestion de données

Bref, la construction de rapports et leur utilisation dans des applications architecturés autour de concepts proches de CQRS paraît facile avec MongoDB.

En revanche, ce qui me paraît beaucoup plus compliqué, c’est la construction de données historisées « sans fin » (à cause par exemple de la limite dans la taille des documents).

Et puis, après avoir bossé sur des bases graphes, je dois bien reconnaître que je reste très attaché au graphe, c’est-à-dire à la création, et à la gestion de cohérence de ces liens par le système. Or c’est précisément le sujet que MongoDB ne veut pas adresser (et je les comprend, parce que ça simplifie bien des choses).

Cela étant, c’était une sacrément chouette session. Merci au chtijug !

Cinq ans, putain !

Comme il me reste plus que cinq jours de présence dans celle qui sera bientôt mon ancienne entreprise, je pense que le moment est parfaitement adéquat pour me lancer dans une petite série d’articles revenant sur ces cinq années de présence dans une boîte qui s’est appelée Perigee.

Je vais, pour ce premier article, ne pas vous parler de ce qui m’a occupé pendant quatre de ces cinq années : une espèce d’usine à gaz permettant de générer des catalogues grâce à Indesign.

Parce que la technique est chiante. Surtout quand c’est l’une de ces horreurs dont Adobe a le secret (oui, je parle d’Indesign).

Parce que, quand ce projet a commencé, l’idée (en 2010, donc) de créer un nouveau logiciel dont le seul objectif était de produire du papier me paraissait anachronique (pour être gentil).

Bref …

En fait, c’est la première fois dans ma carrière que j’ai eu la chance de pouvoir prendre des décisions impactantes pour un développement logiciel, mais aussi la première fois que j’ai pu vivre un projet de la première idée farfelue à sa réalisation concrète. Et même si le projet est un échec commercial, c’est également, de mon point de vue, une certaine forme de réussite technique … une réussite aussi évidente que pourrait l’être, dans un autre domaine, un aéroglisseur de transport de troupes : en dehors de son domaine d’utilisation, c’est lourd, lent, pénible, insupportable, même. Mais dans son domaine, c’est la meilleure solution possible … ou presque. Toujours est-il que voir un logiciel se construire de la première à la dernière brique est une sacrée aventure collective.

Et je crois que c’est la principale transformation que m’a fait subir mon mentor local : comprendre que si le codage ets une étape nécessitant de la tranquilité, le développement d’un logiciel, pris comme un tout, est avant tout un travail d’équipe nécessitant de la communication. Et pas n’importe laquelle. J’ai l’impression que le développement st de l’ordre de la maïeutique. En effet, l’équipe dans son ensemble cherche à donner corps à une idée, pour le simple développement, ou à comprendre ce qui dysfonctionne, dans le cas plus courant de la correction de bug.

Quoi ?

Vous me dites que vous ne comprenenez pas pourquoi je parle plus de correction de bugs que de développement ?

Eh bien c’est aussi l’une des grandes leçons de ce développement : même pour un nouveau développement, même pour un bout de code qui n’a pas encore passé l’épreuve du client, on passe plus de temps à reprendre du code qu’à en écrire du nouveau.

Et je pourrais développer ça sur quinze pages, mais ça me forcerait à entrer dans des considérations techniques qui ne sont pas le sujet de ce texte … mais peut-être du prochain.