Skip to content

Blogs de Développeurs: Aggrégateur de Blogs d'Informatique sur .NET, Java, PHP, Ruby, Agile, Gestion de Projet

Forum Logiciel

Forum Logiciel : diffusion de connaissance et d’informations sur toutes les activitĂ©s liĂ©es au dĂ©veloppement d’applications informatiques en entreprise.

Agrégateur de flux

[ATN2017] Ouverture de la billetterie !

Agile Nantes - sam, 08/12/2017 - 13:26
Vous l’attendiez tous avec impatience :   La premiĂšre salve d’inscription pour l’Agile Tour Nantes, qui se tiendra le jeudi 16 novembre prochain est ouverte !  Rendez-vous sur la page officielle : http://www.agilenantes.org/agile-tour-nantes-2017/ L’appel Ă  Orateur est encore ouvert. L’appel Ă  sponsor est Ă©galement encore ouvert.
Catégories: Association

LCC 175 - Interview sur la build avec CĂ©dric Champeau et Arnaud HĂ©ritier - partie 2

Guillaume, Cédric et Arnaud se retrouvent autour du micro pour parler pendant une session marathon de 3h30 du build, de Maven et de Gradle. Dans cette deuxiÚme partie, on y discute tests puis on aborde des questions spécifiques à chaque outil. On aborde enfin le dilemme: migrer ou ne pas migrer, telle est la question. Le tout basé sur les questions posées sur la mailing list des cast codeurs : merci à vous !

Enregistré le 19 juillet 2017

TĂ©lĂ©chargement de l’épisode LesCastCodeurs-Episode–175.mp3

Interview

 

Ta vie ton Ɠuvre

CĂ©dric Champeau Gradle Inc. Arnaud HĂ©ritier Cloudbees

Gradle Maven

Les tests

Gradle / Maven: Quelle est la philosophie officielle des deux outils pour la gestion des tests au delĂ  des tests unitaires (une fois les diffĂ©rents modules assemblĂ©s et dĂ©ployĂ©s) ? Dans des projets maven par exemple, je vois des fois des modules dĂ©diĂ©s, en scope test ou scope runtime et lancĂ©s Ă  la main, d’autres fois des projets indĂ©pendants. Chaque Ă©quipe a plus ou moins sa propre façon de gĂ©rer la chose mais rien n’a l’air vraiment normalisĂ© (ou du moins partagĂ© par la communautĂ©).

Gradle / Maven: Quels sont les ‘best practices’ pour faire du ‘test and watch’ (genre infinitest) avec maven et gradle ?

Les intégrations

Gradle: Pourquoi je ne peux pas faire de Run Tests sur un projet en Gradle dans IntelliJ alors qu’avec Maven je peux ? Gradle / Maven: Pour les deux, qu’en est il de l’intĂ©gration dans les diffĂ©rents IDE ? J’ai Ă©tĂ© agrĂ©ablement surpris par l’intĂ©gration de Gradle dans Netbeans, mais je n’ai pas beaucoup jouĂ© avec. Gradle / Maven: “Quid de l’intĂ©gration dans mon IDE prĂ©fĂ©rĂ© ?” Gradle / Maven: “Quid de l’intĂ©gration dans mon continuous build prĂ©fĂ©re ?”

Gradle en profondeur

Gradle: Y’a moyen de voir en Gradle à quel test je suis rendu ?

Gradlew/mvnw
  • Gradle: Pourquoi mvnw et gradlew ne downloadent par leurs jars au lieu de nous forcer Ă  les mettre dans .mvn et gradle ?
  • Gradle: Pour Gradle, vous ne trouvez pas affreux ces fichiers “gradlew” et “gradlew.bat” Ă  la racine de chaque projet dans github ?
Scripting vs XML
  • Gradle: Est-il prevu de pouvoir avoir un fichier build.gradle a chaque niveau de la hierarchie de tes modules au lieu d’avoir besoin de decrire manuellement tous les paths dans un fichier settings.gradle ? C’est un point que j’ai trouvĂ© penible (par ex https://github.com/xwiki/xwiki-commons/blob/master/settings.gradle et lĂ  je ne liste que qq modules - en pratique il y en a des centaines ds le build xwiki).
  • Gradle: Est-ce que Gradle travaille a essayer d’homogĂ©nĂ©iser encore plus les builds Gradle ? Qd j’ai essayĂ© de convertir le build Maven de XWiki en Gradle, j’ai lu la doc puis j’ai regarde 4–5 builds differents en gradle pour voir les bonnes practices. Et la j’ai ete embete car chacun avait des pratiques un peu differentes. Au debut j’etais meme paumĂ© et puis apres qq heures de recherches j’ai commencĂ© Ă  identifier des patterns communs mais qd meme avec pas mal de variations. Du coup je n’ai pas su trouver facilement les best practices et j’ai du me les faire et en consequence le build Gradle XWiki est lui aussi encore un peu different des autres probablement. Qu’est-il prevu sur le sujet ? En gros comme simplifier encore plus l’onboarding Gradle ?
BOM

Gradle: Le BOM de maven est-il une invention du malin ? Et quel est son Ă©quivalent pour Gradle ?

Android

Gradle: Pourquoi l’intĂ©gration de ces outils dans Android Studio est-elle aussi pathĂ©tiquement mauvaise ? (je suis obligĂ© d’utiliser ce sous-outil, et j’ai mal Ă  mon gradle : je ne peux pas voir mes dĂ©pendances facilement, et l’intĂ©gration se rĂ©sume Ă  une lecture de la liste des tĂąches et Ă  leur lancement).

Maven en profondeur

Maven: Quand est-ce que le bogue Maven du shade plugin qui ne remplace pas le jar d’origine pas le jar shadĂ© sera corrigĂ©? (et que donc l’équipe Maven reviendra Ă  la raison) ? Maven: Pour revenir au cycle de vie de Maven, serait-il possible de configurer des cycles de vies (notion de descripteurs de cycles de vie). En gros, pouvoir dire que mon projet suit un cycle de vie Ă  3 phases qui sont “resource, compile, install” et qu’un autre avec X phases comme compile, “prepare, 
, install, deploy-maven-repository, deploy-env”) Maven: Pour Maven encore, il y avait il me semble un projet polyglot pour les descripteurs, qu’en est-il ? Pourrait on imaginer des descripteurs en yaml et/ou json ? Maven: y’a t’il beaucoup de boites qui dev leurs petits plugins Maven perso pour adapter Ă  leurs problĂ©matiques ?

Granularité / découpage de modules avec Maven

Maven: comment gĂ©rer les builds oĂč l’appli finale est la rĂ©sultante de nombreux multi-module Maven project, chacun dans un repo git perso avec leur version. Nous avons des problĂšmes pour gĂ©rer les Ă©volutions de versions de chacun de ces multi-modules et faire en sorte que les modules qui en dĂ©pendent se MAJ vers la nouvelle version. Les BOM Maven sont une piste mais c’est pas clair
 Maven: est-ce une bonne pratique de considĂ©rer comme absolue la rĂšgle selon laquelle tous les modules d’un multi-module Maven project doivent avoir le mĂȘme numĂ©ro de version ? Maven: est-ce bien une mauvaise pratique que de mettre dans le mĂȘme repo Git 2 multi-module Maven projects qui ne partagent pas le mĂȘme parent ? Maven: les devs familiers avec Maven n’ont ils pas trop tendance Ă  dĂ©couper leurs appli en modules Maven alors qu’ils pourraient se contenter des package Java ? Je me rend compte que c’est mon cas perso
 Maven: Pour des grosses applis, faites-vous plusieurs petits builds et un meta-build d’assemblage final agrĂ©geant les petits morceaux ? Ou alors faites-vous un bon gros build qui dure longtemps mais recompile/repackage tout ? Ou alors vous laissez-vous le choix en faisant en sorte de pouvoir faire les 2 (sur Jenkins)

Maven: “classpath too long”: c’est la rĂ©sultante du point prĂ©cĂ©dant. Nous commençons Ă  nous heurter Ă  des problĂšmes de “classpath too long” sous Windows pour des Proof of Concepts mixant de nombreux projets. Le point de non-retour est-il proche ? (Pour info, nous contournons temporairement le problĂšme en ayant utilisĂ© la commande mklink pour simlinker le repo Maven sur c:\repo et gagner quelques caractĂšres sur chaque dĂ©pendance
 oui, c’est tres moche) Maven: quid du paramĂ©trage du build ? Par exemple actuellement nous avons une phase de packaging assez gĂ©nĂ©rique qui prend en entrĂ©e un numĂ©ro de version de l’application Ă  packager. Merci Jenkins.

Migration

Migrer vers Gradle, mais pourquoi (pas) ? Et la valeur du build dans tout ça 
 Gradle: Pourquoi est-ce que depuis 3 ans, je vais voir une prez de CĂ©dric sur Gradle, et j’en ressors en me disant “Gradle, ça a l’air quand mĂȘme vachement bien”, et que l’annĂ©e qui suit, je retourne voir une prez de CĂ©dric l’annĂ©e suivante sans avoir rien changĂ© sur mes projets Java ? Gradle: Suis-je tellement fainĂ©ant dans mon petit confort de build Maven pour reposer sur mes acquis et ne pas switcher ? Je veux dire 
 Ă  chaque fois j’ai de bons arguments apportĂ©s par CĂ©dric pour migrer, et pourtant, le switch ne se fait finalement pas. Gradle / Maven: ConsidĂšre-t-on aujourd’hui le build comme accessoire sur un projet Java pour ne pas vouloir engager un investissement de migration ? (je parle beaucoup de mon cas perso ici, mais j’ai l’impression qu’il n’est pas si isolĂ© que ça) Ou au contraire, est-ce tellement critique et relativement assez peu agile qu’on a trop peur d’en changer? Si on reprend le cas de Ant vs Maven, pas mal de gens ont traine a migrer, c’etait trop risque, les bonnes pratiques etaient encore peu connues, tout le monde avait peur de crasher son projet a cause de ca
 Personne ne veut essuyer les platres d’une “nouvelle” techno de build avec son projet. Gradle: Peut-etre Gradle en est-il encore la et a du mal a passer le cap des Early-Adopters (ceci dit, avec Android et son armee de developpeurs d’apps ca devrait changer vite si c’est le cas; tant qu’Android l’infidele decide de rester sur Gradle :P Gradle: Et enfin, LE point-cle: est-ce que la migration de Maven a Gradle amene une valeur ajoutee suffisante pour justifier l’effort et le risque? J’ai pas l’impression de lire beaucoup de retour d’experience de projets qui disent avoir gagne drastiquement en productivite en en qualite grace a une migration Maven->Gradle. Gradle / Maven: “je dĂ©marre un projet, Gradle ou Maven ?”

Conclusion

Gradle / Maven: les devs et le build: gĂ©nĂ©ralement, la grande majoritĂ© des devs ne s’y intĂ©ressent pas. A titre perso, je trouve ça fondamental, si le build est mal fait, ça handicap tout le projet sans que les gens ne s’en aperçoivent malgrĂ© les effets nĂ©gatifs, ils ne voient pas comment faire autrement => est-ce un ressenti que vous avez ?

Nous contacter

Faire un crowdcast ou une crowdquestion Contactez-nous via twitter https://twitter.com/lescastcodeurs sur le groupe Google https://groups.google.com/group/lescastcodeurs ou sur le site web https://lescastcodeurs.com/ Flattr-ez nous (dons) sur https://lescastcodeurs.com/ En savoir plus sur le sponsoring? sponsors@lescastcodeurs.com

Catégories: Blog Individuel

How to make JIRA the single source for business reports

Le blog de Valiantys - jeu, 08/10/2017 - 14:42

The following is a guest blog written by Levente Szabo, the Digital Marketing Manager at Midori. Midori is a Marketplace vendor that builds add-ons to enhance Atlassian JIRA, Confluence and Bitbucket with additional features.   If you look “under the hood” of an enterprise business operation, you’ll find a vast number of information systems, intertwined sometimes ...

The post How to make JIRA the single source for business reports appeared first on Valiantys - Atlassian Platinum Partner.

Catégories: Blog Société

MythBuster: Apache Spark ‱ Épisode 2: Planification et exĂ©cution d’une requĂȘte SQL


Nous poursuivons aujourd’hui notre sĂ©rie d’articles dĂ©diĂ©e Ă  la dĂ©mystification de Spark et plus particuliĂšrement au moteur d’exĂ©cution Tungsten.

Pour rappel, dans l’Ă©pisode prĂ©cĂ©dent, nous sommes partis d’une requĂȘte SQL sous forme de String que nous avons d’abord dĂ©coupĂ©e en une instance de Seq[Token] grĂące Ă  notre classe Lexer, puis en une instance d’AST grĂące Ă  notre classe Parser. L’abre formĂ© par l’AST obtenu en sortie permet d’avoir une structure avec laquelle il est relative simple d’intĂ©ragir au travers de notre code.

Dans cet Ă©pisode, nous allons chercher Ă  transformer cet AST en un plan d’exĂ©cution, ce qui sera l’occasion de plonger au coeur du moteur d’optimisation Catalyst, dont nous dĂ©taillerons certains mĂ©canismes utilisĂ©s dans la version 2.2 de Spark.

Nous aurons alors tout le matĂ©riel nĂ©cessaire pour mettre en place un modĂšle de gĂ©nĂ©ration de code similaire Ă  celui de Spark, que nous traiterons dans le troisiĂšme Ă©pisode cette sĂ©rie d’article.

L’ensemble du code dont nous allons parler ci-dessous est disponible dans notre dĂ©pĂŽt GIT. N’hĂ©sitez-pas Ă  aller y faire un tour !

Planification Un peu de théorie


Reprenons notre cheminement. GrĂące Ă  l’Ă©pisode prĂ©cĂ©dent, nous sommes capables d’avoir une reprĂ©sentation sĂ©mantique d’une requĂȘte SQL exprimĂ©e au dĂ©part sous forme de texte. L’AST, produit en sortie du Parser, permet en effet de donner un sens Ă  la requĂȘte d’origine, et de l’exploiter plus facilement grĂące Ă  sa structure d’arbre.

Maintenant que nous sommes capable de donner un sens Ă  cet requĂȘte au travers du code, nous allons devoir dĂ©terminer quelle est la meilleure façon de l’exĂ©cuter. C’est lĂ  qu’interviennent successivement le Logical Plan (ou plan d’exĂ©cution logique) et le Physical Plan (ou plan d’exĂ©cution physique).

Plan d’exĂ©cution logique

Il s’agit d’un arbre (oui, encore un) qui modĂ©lise l’ensemble des opĂ©rations ensemblistes nĂ©cessaires pour exĂ©cuter la requĂȘte SQL. La Projection, le Filtre, la Jointure sont des exemples d’opĂ©rations ensemblistes qui peuvent faire partie du plan d’exĂ©cution logique.

En clair, le plan d’exĂ©cution logique dĂ©crit l’ensemble des Ă©tapes nĂ©cessaires pour exĂ©cuter une requĂȘte.

Plan d’exĂ©cution physique

Le plan d’exĂ©cution physique dĂ©crit la maniĂšre dont ces opĂ©rations ensemblistes vont ĂȘtre rĂ©alisĂ©es. Il se distingue en cela du plan d’exĂ©cution logique qui, lui, ne dĂ©crit que de façon abstraite les opĂ©rations Ă  effectuer.

ConcrĂštement, le plan d’exĂ©cution physique comprend l’ensemble du code qui va ĂȘtre utilisĂ© pour exĂ©cuter une requĂȘte SQL.

Un Join peut p. ex. ĂȘtre rĂ©alisĂ© par :

  • Un Hash Join (on va indexer dans une map toutes les valeurs de l’une des deux tables, et itĂ©rer sur la seconde en rĂ©alisant un lookup dans la map crĂ©Ă©e auparavant) : cet algorithme est efficace lorsque l’une des deux tables est suffisamment petite pour ĂȘtre indexĂ©e en mĂ©moire. Dans Spark, on part alors plus spĂ©cifiquement de Broadcast Hash Join.
  • Ou bien un Nested Loop Join (on va rĂ©aliser deux boucles imbriquĂ©es avec une comparaison Ă  chaque sous-itĂ©ration) : cet algorithme est applicable quelle que soit la taille des tables en jeu, mais nĂ©cessite de re-parcourir les tables Ă  chaque fois (sauf si elles sont mises en cache, et l’on parle alors de Block Nested Loop)

Ces deux types de Join ne sont pas exhaustifs et sont plutĂŽt les reprĂ©sentants simplistes de deux familles : il existe en effet de nombreuses autres implĂ©mentations qui reposent sur des optimisations de l’un ou l’autre des algorithmes (p. ex. le Sort-Merge Join est semblable au Nested Loop Join mais est plus rapide sur des tables dĂ©jĂ  triĂ©es par leurs clĂ©s de jointure).

L’Ă©tape qui va permettre de passer du plan d’exĂ©cution logique au plan d’exĂ©cution physique correspond Ă  ce que l’on appelle la planification : c’est lors de cette Ă©tape que vont ĂȘtre mis en relation le modĂšle logique de donnĂ©es et le modĂšle physique. Sur la plupart des SGBDR, il est possible de rĂ©cupĂ©rer ce plan d’exĂ©cution en utilisant les commandes EXPLAIN ou EXPLAIN PLAN.

DĂ©tail d’un plan d’exĂ©cution physique sous Oracle

Durant l’Ă©tape de planification, nous avons quasiment une relation 1-pour-1 entre le Logical Plan et le Physical Plan, et c’est lors de l’Ă©tape d’optimisation que le le Physical Plan sera susceptible d’Ă©voluer pour obtenir de meilleures performances lorsque notre requĂȘte sera exĂ©cutĂ©e


Optimisations

Les optimisations correspondent Ă  un ensemble de transformations que l’on va appliquer Ă  nos plans d’exĂ©cution logiques et physiques de maniĂšre Ă  accĂ©lĂ©rer la requĂȘte. C’est en appliquant des optimisations sur nos diffĂ©rents plans d’exĂ©cution que l’on comprend tout l’intĂ©rĂȘt de distinguer l’aspect logique de l’aspect physique :

  • Dans le cas d’un plan d’exĂ©cution logique, les optimisations ne vont ĂȘtre qu’ensemblistes ou bien rĂ©alisĂ©es sur les Expressions. Il s’agit d’optimisations gĂ©nĂ©riques pour lesquels peu (voire pas) d’informations sur la donnĂ©e sont nĂ©cessaires. P. ex., sans connaissance prĂ©alable du contexte, on sait qu’il est intĂ©ressant de regrouper plusieurs filtres successifs en un seul, ou bien Ă©valuer des constantes, factoriser des termes

  • Dans le cas du plan d’exĂ©cution physique, les optimisations vont ĂȘtre rĂ©alisĂ©es sur la maniĂšre dont on accĂšde aux donnĂ©es (p. ex. dĂ©porter un filtre directement dans la base de donnĂ©es source quand c’est intĂ©ressant, on parle alors de Predicate Pushdown) ainsi que sur la maniĂšre dont les relations vont ĂȘtre rĂ©alisĂ©es en fonction des mĂ©tadonnĂ©es des tables en jeu (les stats d’Oracle, ça vous rappelle quelque-chose ?)
Notre implémentation ! Petit focus sur le trait TreeNode

Avant de rentrer dans le détail en tant que tel, nous allons commencer par décrire le trait TreeNode défini dans le fichier TreeNode.scala, qui va nous servir de structure de base à plusieurs reprises.

Ce trait modélise une structure en arbre habituelle : chaque instance de type TreeNode peut faire référence entre 0 et plusieurs fils eux aussi de type TreeNode. Cependant, deux propriétés rendent ce trait vraiment intéressant :

  • Chaque instance d’une classe implĂ©mentant TreeNode doit ĂȘtre immutable (et ne peut donc pas ĂȘtre altĂ©rĂ©e)
  • Tout comme une instance de Seq peut ĂȘtre transformĂ©e Ă  l’aide de la mĂ©thode map(), une instance d’une classe implĂ©mentant TreeNode peut-ĂȘtre transformĂ©e Ă  l’aide de la la mĂ©thode transformDown()pour modifier l’ensemble des enfants de l’arbre
  • Le trait TreeNode possĂšde une annotation self-type du type qui va l’implĂ©menter (ce qui va nous permettre d’utiliser ce trait de maniĂšre totalement transparente dans notre code, sans ne jamais le rĂ©fĂ©rencer)

Nous pouvons p. ex. voir dans le fichier TreeSpec.scala qu’il est possible de dĂ©crire la rĂšgle de factorisation d’entier et l’appliquer sur une expression quelconque en quelques lignes seulement :

expression.transformDown {
  case Add(Multiply(a, b), Multiply(c, d)) => (a, b, c, d) match {
    case _ if a == c => Multiply(a, Add(b, d))
    case _ if a == d => Multiply(a, Add(b, c))
    case _ if b == c => Multiply(b, Add(a, d))
    case _ if b == d => Multiply(b, Add(a, c))
  }
}

On traverse notre arbre d’expressions, et chaque fois qu’un noeud correspond Ă  la forme Add(Multiply, Multiply), on applique notre factorisation. Les autres noeuds restent inchangĂ©s ! Notons que l’on s’appuie fortement sur la notion de PartialFunction de Scala.

Dans la suite de cet article, nous allons voir que de nombreux concepts reposent sur des structures de donnĂ©es en arbre. C’est pourquoi ce trait TreeNode est central dans notre implĂ©mentation, car bon nombre de nos classes vont s’appuyer dessus.

Les classes LogicalPlan, PhysicalPlan et QueryPlanner

Tout comme Spark, nous nous reposons fortement sur les case classes et la notion de Pattern Matching pour convertir notre AST de départ en une instance de LogicalPlan.

Le trait LogicalPlan

Ce trait LogicalPlan et l’ensemble de ses implĂ©mentations est dĂ©fini au sein du fichier LogicalPlan.scala. Il est intĂ©ressant de noter que ce trait Ă©tend TreeNode (et correspond donc Ă  une structure en arbre) mais n’impose l’implĂ©mentation d’aucune mĂ©thode : il ne s’agit en effet que d’une reprĂ©sentation sĂ©mantique de notre requĂȘte SQL. La structure d’arbre est quant Ă  elle utile pour effectuer facilement des transformations qui vont servir Ă  optimiser le plan logique d’exĂ©cution.

trait LogicalPlan extends TreeNode[LogicalPlan]

C’est la mĂ©thode apply de notre companion object LogicalPlan qui va ĂȘtre en charge de transformer notre instance d’AST, obtenu en sortie du parsing, en une instance de LogicalPlan. Ou plus prĂ©cisĂ©ment en un Try[LogicalPlan] car la conversion peut Ă©chouer si notre AST n’est pas valide.

C’est lui qui fait le lien entre la sĂ©mantique de notre requĂȘte SQL et sa reprĂ©sentation en termes d’opĂ©rateurs. Il devient ainsi possible de raisonner d’un point de vue purement logique au moment d’optimiser notre requĂȘte.

La classe LogicalPlanOptimizer.scala a pour but de rassembler l’ensemble de ces rĂšgles d’optimisation (qui sont encore en cours de dĂ©veloppement).

Le trait PhysicalPlan

Le trait PhysicalPlan et l’ensemble de ses implĂ©mentations sont prĂ©sents au sein du fichier PhysicalPlan.scala. Le trait est relativement semblable Ă  celui dĂ©fini ci-dessus, hormis qu’il est cette fois nĂ©cessaire d’implĂ©menter la mĂ©thode execute() qui doit retourner un Iterator[InternalRow]. Elle sera appelĂ©e lors de l’exĂ©cution effective de notre requĂȘte. Nous parlerons plus en dĂ©tail de cette mĂ©thode par la suite.

trait PhysicalPlan extends TreeNode[PhysicalPlan] {
    def execute() : Iterator[InternalRow]
}

Notons Ă  titre d’exemple la classe CSVFileScan qui va lire des lignes d’un fichier CSV et les retourner sous forme d’InternalRow : c’est grĂące Ă  cette classe que nous allons pouvoir utiliser validations.csv et pedestrians_in_nation.csv comme tables.

Les optimisations du plan d’exĂ©cution physique sont listĂ©es dans PhysicalPlanOptimizer.scala et dĂ©finies dans package.scala. C’est justement au sein de ces rĂšgles d’optimisation que l’on se rend compte de la puissance du trait TreeNode associĂ© au Pattern Matching de Scala.

La classe QueryPlanner

La conversion entre le LogicalPlan et le PhysicalPlan est rĂ©alisĂ©e Ă  l’aide du QueryPlanner Ă  cet endroit dĂ©fini dans le fichier QueryPlanner.scala.

Du cÎté de chez Spark

Le mĂ©canisme que nous avons mis en place est vraiment trĂšs similaire Ă  celui que Spark propose au sein de son moteur d’optimisation Catalyst. Les plans logiques et physiques sont reprĂ©sentĂ©s par des arbres sur lesquels des optimisations peuvent ĂȘtre effectuĂ©es.

De mĂȘme, les Expressions sont traitĂ©s comme des arbres Ă  part entiĂšre (qui implĂ©mentent donc la classe TreeNode). Pour simplifier, les Expressions correspondent aux opĂ©rations appliquĂ©es sur les colonnes notamment pour les Projections ou les Filters.

P. ex. pour la requĂȘte : SELECT 2 * (longueur + 1) FROM rectangles, le terme 2 * (longueur + 1) correspond Ă  une Expression qui peut ĂȘtre reprĂ©sentĂ©e sous la forme suivante Multiply(Constant(2), Add(Literal("longueur"), Constant(1))).

L’avantage, encore une fois, est que l’on peut appliquer facilement des optimisations sur les Expressions en effectuant des opĂ©rations sur les arbres.

Dans Spark, les optimisations s’appliquent donc Ă  la fois aux opĂ©rateurs et aux Expressions. C’est la classe Optimizer dĂ©finie dans Optimizer.scala qui rĂ©pertorie l’ensemble des optimisations et qui sert de classe de base du SparkOptimizer (c’est ici que l’on trouve l’ensemble des rĂšgles appliquĂ©es !).

La classe SparkPlan correspond à la classe de base des classes Exec qui correspondent à nos PhysicalPlan est définie dans le fichier SparkPlan.scala.

Enfin, le fichier SparkStrategies.scala contient l’ensemble des stratĂ©gies qui permettent de passer d’un plan d’exĂ©cution logique Ă  un plan d’exĂ©cution physique (les classes Exec) en se basant sur le QueryPlanner et (avec comme implĂ©mentation le SparkPlanner, les stratĂ©gies utilisĂ©es sont d’ailleurs dĂ©clarĂ©es au sein de ce dernier).

Pour aller plus loin
 User Defined Fonctions et optimisations

Comme beaucoup de moteurs SQL, Spark offre la possibilitĂ© de dĂ©finir ses propres fonctions Ă  appliquer dans des requĂȘtes SQL : les User Defined Fonctions ou UDF. En pratique, lorsqu’on dĂ©finit une UDF cela correspond Ă  crĂ©er une nouvelle implĂ©mentation de l’interface Expression, comme le montre la classe ScalaUDF. La fonction dĂ©finie par l’utilisateur sert alors d’implĂ©mentation Ă  la mĂ©thode eval du trait Expression.

De ce fait, les UDF offrent une grande souplesse pour le dĂ©veloppeur qui peut utiliser n’importe quel code Scala au sein de sa requĂȘte SQL. NĂ©anmoins, cette libertĂ© a un coĂ»t puisque le moteur Catalyst n’est plus capable de comprendre le contenu de l’Expression et d’appliquer des optimisations dessus : une UDF est perçue par Spark comme une boĂźte noire. Il est donc important de les utiliser avec parcimonie pour Ă©viter des problĂšmes de performances (voir Performance Considerations).

NĂ©anmoins, depuis Spark 2.0, il est possible d’implĂ©menter ses propres rĂšgles d’optimisation et ainsi tenir compte de ses propres UDF (dont seul l’utilisateur connait le contenu).

Apache Calcite
 Le retour !

Nous avons déjà mentionné Apache Calcite dans le premier article de cette série étant donné que ce framework permet de résoudre de maniÚre générale les problématiques inhérentes au parsing SQL


Il se trouve que Calcite possĂšde Ă©galement son propre moteur d’optimisation (qui est, lui aussi, utilisĂ© par Hive).

Cost Based Optimizer

Jusqu’Ă  la version 2.2 de Spark, l’optimisation des plans d’exĂ©cution se basait uniquement sur des rĂšgles indĂ©pendantes des donnĂ©es elles-mĂȘmes, et ignorait certaines informations comme :

  • La cardinalitĂ© des lignes qui vont ĂȘtre vont ĂȘtre produites par un plan d’exĂ©cution (p. ex., pour le produit cartĂ©sien va produire N × M lignes si le premier fils produit N lignes et le seconds fils M lignes)
  • La maniĂšre dont les donnĂ©es sont distribuĂ©es (p. ex., combien y a-t-il d’Ă©lĂ©ments distincts)

En fonction de ces informations supplĂ©mentaires, il peut ĂȘtre intĂ©ressant d’optimiser diffĂ©remment le plan d’exĂ©cution : plus le contexte de la requĂȘte exĂ©cutĂ©e est connu, plus l’optimisation sera pertinente. On parle alors de Cost Based Optimization.

Ces notions doivent rappeler des souvenirs aux utilisateurs de SGBDR
 On retrouve en effet ici les fameuses statistiques qui ont causé du fil à retordre à nos DBA préférés.

Depuis Spark 2.2, on voit apparaĂźtre dans le code des fonctionnalitĂ©s relatives Ă  ces statistiques (on peut p. ex. voir dans Statistics.scala la maniĂšre dont elle sont stockĂ©es et elle seront a priori exploitĂ©es dans QueryExecution.scala qui pour l’instant prend le premier plan d’exĂ©cution physique).

Execution

Toujours en partant de notre requĂȘte SQL sous forme de String, nous avons Ă  prĂ©sent un PhysicalPlan qui dĂ©crit de maniĂšre exhaustive ce qui doit ĂȘtre rĂ©alisĂ© pour obtenir un rĂ©sultat
 Il n’y a donc plus qu’Ă  exĂ©cuter la requĂȘte ! Et c’est pour cela que nous allons implĂ©menter la fameuse mĂ©thode execute()


Un peu de théorie La notion de Volcano Model

Le plan d’exĂ©cution physique modĂ©lise le parcours de chaque tuple d’origine (qui est issu d’une table) pour aboutir (ou non, p. ex. s’il est filtrĂ© au niveau d’une clause WHERE) au rĂ©sultat de la requĂȘte.

Depuis plus d’une vingtaine d’annĂ©e, la maniĂšre dont les plans d’exĂ©cution physique sont executĂ©s repose sur la notion de Volcano Model, dont les bases ont Ă©tĂ© thĂ©orisĂ©es au sein de ce papier (qui date de 1994 !). Oracle, PostgreSQL, etc. reposent en grande partie sur cette notion.

Le Volcano Model se base sur trois principes :

  • Faire correspondre Ă  chacune des Ă©tapes du plan d’exĂ©cution logique une Ă©tape du plan d’exĂ©cution physique
  • Le deuxiĂšme principe repose sur le fait que toutes les Ă©tapes du plan d’exĂ©cution physique sont chaĂźnĂ©es (chaque Ă©tape mĂšre est associĂ© Ă  une ou plusieurs Ă©tapes filles) : Ă  chaque Ă©tape correspond donc un opĂ©rateur
  • Enfin, Ă©tant donnĂ© que l’objectif du plan d’exĂ©cution physique est d’Ă©valuer la requĂȘte, le troisiĂšme principe spĂ©cifie que l’on va laisser le parent contrĂŽler le flux des tuples qui vont naviguer d’un opĂ©rateur Ă  l’autre en demandant aux enfants les tuples un par un

Il est intéressant de noter que le Volcano Model repose sur le principe de pull de la donnée : le parent demande aux enfants le prochain tuple à traiter.

Principe du Volcano Model

L’exemple ci-dessus modĂ©lise donc un filtre Filter appliquĂ© sur le produit cartĂ©sien Cartesian Product de deux sources de donnĂ©es Scan : pour peu que ce filtre permette de faire le lien entre nos deux sources de donnĂ©es, nous avons ici l’exemple d’une jointure naĂŻve rĂ©alisĂ©e avec la combinaison de 3 opĂ©rateurs !

Notre implémentation ! Nos types de base

Nous allons commencer par dĂ©finir le type InternalRow qui va correspondre Ă  une ligne. Une ligne est composĂ©e de colonnes de type InternalColumn (qui peut ĂȘtre issu d’une table identifiĂ©e par son nom de type RelationName ou d’une expression) identifiĂ©e par un nom de type ColumnName et Ă  chaque colonne correspond une valeur de type Any.

De ce fait :

type Name = String
type ColumnName = Name
type RelationName = Name
type InternalColumn = (Option[RelationName], ColumnName)
type InternalRow = Map[InternalColumn, Any]
La mĂ©thode execute() L’idĂ©e gĂ©nĂ©rale

Le passage d’une instance de LogicalPlan vers une instance de PhysicalPlan a Ă©tĂ© effectuĂ© Ă  l’aide du QueryPlanner dont nous avons parlĂ© ci-dessus. Nous n’avons par contre pas parlĂ© de l’objectif de la mĂ©thode execute() de notre trait PhysicalPlan qui doit ĂȘtre dĂ©finie au sein des implĂ©mentations.

Le contrat Ă©tabli par les opĂ©rateurs du Volcano Model ressemble beaucoup Ă  celui rempli par l’interface Iterator de Scala
 En effet, chaque opĂ©rateur va rĂ©cupĂ©rer 1 par 1 les tuples qu’il va traiter. Eh bien capitalisons lĂ -dessus en imposant Ă  cette mĂ©thode execute()de retourner un Iterator[InternalRow].

Pour rappel :

trait Iterator[E] {

    def next(): E

    def hasNext: Boolean

}
Implémentation du Filter

On a notre base de travail : notre trait est défini. On peut maintenant implémenter un Filter :

case class Filter(child: PhysicalPlan, predicate: Predicate) extends PhysicalPlan {

  override def execute(): Iterator[InternalRow] = {

    child.execute().filter(predicate.evaluate)

  }

}

On constate alors que Filter fait rĂ©fĂ©rence Ă  l’opĂ©rateur prĂ©cĂ©dent nommĂ© child. En effet, pour chaĂźner l’ensemble des opĂ©rateurs, chacun d’eux va devoir rĂ©fĂ©rencer celui qui le prĂ©cĂšde, comme un arbre. Filter collecte ainsi 1 par 1 les tuples renvoyĂ©s par l’opĂ©rateur qui le prĂ©cĂšde et applique sur chacun d’eux le un Predicate (i.e. vĂ©rifie si une condition est respectĂ©e).

Puisque chaque opĂ©rateur appelle le prĂ©cĂ©dent, le dernier opĂ©rateur Ă  traiter un tuple est celui qui va servir de point d’entrĂ©e au traitement : on demande au dernier opĂ©rateur de lancer le traitement, qui va alors demander Ă  son (ou ses) enfants de lancer leurs propres traitements et ainsi de suite. On retrouve bien ici le mode pull dont nous parlions prĂ©cĂ©demment. Ce fonctionnement n’est en fait qu’une consĂ©quence direct de la description de notre plan physique sous forme d’arbre : c’est le noeud racine de l’arbre qui rĂ©fĂ©rence tous les autres. Lorsque l’on appelle la mĂ©thode execute() sur ce noeud, on appelle execute() sur l’ensemble de ses enfants, et ainsi de suite jusqu’Ă  arriver Ă  la source de donnĂ©es.

Chaque tuple traitĂ© doit ainsi traverser chacune des classes de chacun des opĂ©rateurs du plan physique. La modularitĂ© du modĂšle vient du fait qu’il est facile de chaĂźner de nouveaux opĂ©rateurs entre eux, et de faire des optimisations notamment en modifiant l’ordre des diffĂ©rents opĂ©rateurs.

DĂ©monstration de bout en bout

Du cÎté de chez Spark


La classe SparkPlan qui correspond à la classe de base des classes Exec qui correspondent à nos PhysicalPlan sont défini au sein de SparkPlan.scala

Il est intĂ©ressant de noter que, dans Spark, les RDD sont utilisĂ©s, alors notre implĂ©mentation se base sur des Iterator, et c’est ça la force de Spark SQL puisque le calcul va ĂȘtre distribuĂ© ! L’itĂ©rateur est ainsi partagĂ© entre plusieurs machines. Mais ça, ça sera pour un prochain article


Pour aller plus loin Predicate Pushdown

Une autre optimisation intĂ©ressante que propose Spark en termes de plan d’exĂ©cution physique est le fait de pouvoir dĂ©lĂ©guer certaines opĂ©ration directement Ă  la source de donnĂ©es : c’est ce que l’on appelle le Predicate Pushdown.

Typiquement, si les donnĂ©es d’un DataFrame sont issues d’une base de donnĂ©es, il est possible d’effectuer le filtre directement au niveau de la base de donnĂ©es et de ne renvoyer Ă  Spark que les donnĂ©es qui ont pu valider ce premier filtre. La quantitĂ© de donnĂ©es Ă  transfĂ©rer est donc rĂ©duite.

RDD vs Dataframe vs Dataset

Maintenant que nous voyions Ă  quoi ressemble les mĂ©canismes sous-jacents Ă  l’exĂ©cution d’une requĂȘte dans Spark, faisons un point sur les 3 structures proposĂ©es par le framework pour manipuler des donnĂ©es.

A noter que depuis Spark 2.0, le Dataframe n’est qu’un sous-cas non typĂ© du Dataset. La plupart des optimisations appliquĂ©es Ă  l’un sont donc applicables Ă  l’autre.

Le gros intĂ©rĂȘt d’utiliser les Dataset ou Dataframe est de profiter de toutes les optimisations dĂ©crites dans cet article. La requĂȘte SQL dĂ©crit le besoin de l’utilisateur et le rĂŽle du moteur d’optimisation Catalyst est de trouver le moyen le plus rapide d’apporter la rĂ©ponse Ă  ce besoin.

Une nouvelle problĂ©matique survient lorsque l’utilisateur dĂ©cide d’utiliser ses propres fonction en passant p. ex. par l’opĂ©rateur map() sur une instance d’un DataFrame. Dans ce cas lĂ , on sort du contexte SQL et le code est perçu comme une boĂźte noire par Catalyst : c’est l’utilisateur qui dĂ©crit la solution technique au lieu d’exprimer un besoin.

Jusqu’Ă  la version 1.5 de Spark, la mĂ©thode map(), appliquĂ©e Ă  un DataFrame renvoyait un RDD car le contenu de l’itĂ©rateur ne correspond plus Ă  un tuple classique (une Row), mais Ă  objet Java ou Scala. L’utilisateur prenait alors la responsabilitĂ© d’apporter une solution technique performante, car Catalyst n’Ă©tait plus en mesure de fournir ses optimisations.

A partir de la version 1.6, et avec l’arrivĂ©e des Dataset, il devient possible d’avoir un itĂ©rateur d’objets Java ou Scala (le DataFrame n’est alors plus qu’un Dataset[Row]). La mĂ©thode map() permet ainsi de renvoyer un DataSet Ă  partir d’un autre DataSet. La mĂ©thode map() est alors interprĂ©tĂ©e comme un opĂ©rateur du LogicalPlan. NĂ©anmoins, son contenu reste inconnu Ă  Catalyst. Chaque tuple doit ainsi ĂȘtre dĂ©sĂ©rialisĂ© puis resĂ©rialisĂ© pour pouvoir travailler sur la donnĂ©e.

Une piste d’amĂ©lioration envisagĂ©e pour les versions futures de Spark consiste Ă  interprĂ©ter le contenu de la fonction passĂ©e en paramĂštre de la mĂ©thode map() en Ă©tudiant directement le bytecode qui le constitue, c’est-Ă -dire en regardant comment la fonction est compilĂ© par le compilateur Java ou Scala.

L’objectif final serait de vĂ©rifier automatiquement s’il est possible de traduire cette fonction en une succession d’opĂ©rateurs SQL classiques : on veut traduire la boĂźte noire en opĂ©rateurs interprĂ©tables (et donc optimisables) par Catalyst.

Les travaux actuels sur le sujet s’appuient sur Javassist pour Ă©tudier le bytecode de la fonction. La logique est essentiellement prĂ©sente dans le fichier ClosureToExpressionConverter.scala.

A suivre


Nous avons vu que le Volcano Model est une notion qui n’est pas propre Ă  Spark en tant que tel : de nombreux SGBDR tel que Postgres, MySQL ou mĂȘme Oracle s’appuient sur ce modĂšle.

La grosse amĂ©lioration apportĂ©e par Spark 2.x repose sur le fait qu’il est possible, dans certains cas, de sortir de ce modĂšle standard pour directement gĂ©nĂ©rer le code qui va permettre d’exĂ©cuter la requĂȘte SQL, et ainsi gagner en performance
 Mais ça, c’est pour la suite !

Catégories: Blog Société

Meetup PerfUG : gRPC, échanges à haute fréquence !

Ogury est la plateforme de data mobile qui permet d’accĂ©der aux donnĂ©es comportementales des profils de plus de 400 millions de mobinautes rĂ©partis dans plus de 120 pays.

Une plateforme micro-services c’est cool et c’est Ă  la mode 
 mais il y a aussi le revers de la mĂ©daille ! L’augmentation du traffic inter-services peut dĂ©grader vos temps de rĂ©ponses car les connexions HTTP sont lentes.

Cependant des solutions existent pour optimiser le trafic rĂ©seau, durant cette session, David et Carles vous parleront de la solution qu’ils ont expĂ©rimentĂ©e : gRPC.

David Caramelo, DĂ©veloppeur Craftsman passionnĂ© depuis 12 ans, actuellement Tech Lead full stack chez Ogury. David s’est forgĂ© son expĂ©rience essentiellement dans des startups parisiennes comme Viadeo ou Ogury et dans des cabinets conseil IT comme Xebia.

Carles SistarĂ©, Architecte-DĂ©veloppeur dans les clouds, actuellement Tech Lead de la team Delivery et co-fondateur d’Ogury. Carles a Ă©voluĂ© dans le monde de la AdTech en passant par Ad4Screen et en tant qu’amateur de l’open-source en tant que commiteur Node-Kafka et crĂ©ateur du module grpc-promise.

Inscriptions et informations sur Meetup. Cette session sera suivie d’un pot dans les locaux d’OCTO.

logo

Le PerfUG est un meetup parisien qui a pour objectif d’offrir un lieu d’échanges informels oĂč toutes les personnes intĂ©ressĂ©es par l’optimisation et la performance sont les bienvenues quel que soit leur niveau. Nous sommes convaincus que la performance est une feature implicite et non nĂ©gociable d’une application et pourtant bien souvent oubliĂ©e. Le PerfUG permet d’Ă©changer idĂ©es et pratiques sur ces sujets pour obtenir plus simplement des systĂšmes performants. Le PerfUG souhaite faciliter la diffusion des derniers outils et des meilleures techniques pour maĂźtriser au plus tĂŽt la performance d’un systĂšme informatique.

imgres

Pour en apprendre davantage sur la Performance, retrouvez notre formation OCTO Academy : Performance des applications et du SI Ă  l’Ăšre du digital

Articles suggested :

  1. Compte-rendu du Performance User Group #3
  2. PerfUG : Deep into your native application
  3. High Performance Images

Catégories: Blog Société

La loi de Bigstein ou quand Pirate rencontre Roi

ekito people - lun, 08/07/2017 - 10:15

Vous connaissez ekito, nous accompagnons les Rois et les Pirates.

Lorsqu’il s’agit de les faire se rencontrer, nous sommes souvent confrontĂ©s Ă  trois problĂšmes principaux :

Le temps, les gens, l’image.

 

Le temps : La loi de Bigstein

Ne cherchez pas sur le net, c’est nouveau et lamentablement inspirĂ© d’Einstein. Pourquoi ?

Je cherchais une raison physique, universelle pour comprendre le gouffre qui existe entre ces deux types d’entreprises : les grands groupes et les startups. Puis je me suis souvenu de mes cours de cinĂ©tique.

La formule de l’Ă©nergie donnait : E = 1/2 MVÂČ

Si l’on cherche Ă  comprendre le lien entre la masse et la vitesse, la formule devient :

 

V =  √(2E/M)

 

La vitesse est donc bien proportionnelle Ă  l’inverse de la masse. CQFD, c’est une loi de la nature. Et encore je pense que la racine carrĂ©e sous-estime largement cette inversion de proportionnalitĂ©.

Les startups et les grands groupes sont dans deux Ă©chelles de temps en complĂšte opposition.

La startup est dans l’action, il faut agir rapidement, donc dĂ©cider rapidement. Rien ne l’empĂȘche, pas de risque, c’est un acte entrepreneurial par Ă©vidence, de l’expĂ©rimentation en continu.

Les grands groupes sont pilotés par la gestion du risque, il leur faut du temps pour décider aprÚs de multiples évaluations.

C’est un fait que les deux bords doivent comprendre pour travailler ensemble.

 

Les gens : 3 mois++

Une startup, c’est un, deux, allez… trois fondateurs Ă  la tĂȘte.

Un grand groupe, c’est des chefs, des chefs et des chefs, y a mĂȘme des chefs de chef des fois, mais jamais celui qui va bien.

Il faut au moins 3 mois pour trouver la bonne personne. Celle qui va comprendre l’intĂ©rĂȘt de votre solution. Puis, il y a le “Ah, c’est pas moi qui dĂ©cide”, et lĂ  c’est 3 mois de plus. Ensuite il vous faudra trouver celui qui a le chĂ©quier, qui saura prendre une initiative sans prendre de risques.

 

L’image : Le miroir Ă  deux tĂȘtes

L’image qu’ont les employĂ©s des grands groupes sur ce qu’est une startup : Non, une startup, c’est pas “ping pong et garage”. “ils ne font que s’amuser”, voilĂ  ce que j’ai pu entendre. Cette image vĂ©hiculĂ©e un temps par les mĂ©dias est fort heureusement en train de changer.

Et Ă  contrario, les startups voient les grands groupes comme des grosses machines. Ce qui en un sens est vrai. Mais il y a aussi des grandes entreprises qui innovent encore, qui se mettent de plus en plus en mode “garage” aussi.

Il y a lĂ  un lieu de rencontre possible entre ces deux mondes

Attention toutefois, au startup-washing. Certaines entreprises n’arrivant plus Ă  innover en interne, s’achĂštent des startups, crĂ©ent des incubateurs et au final phagocytent ces jeunes pousses, les freinent dans leur innovation, dans leur approche du marchĂ©. Attention donc aux fausses promesses, aux faux partenariats. Cela peut vous entraĂźner dans un schĂ©ma client / fournisseur qui empĂȘchera toute scalabilitĂ© possible.
Dans ce cas, la startup doit chercher plutĂŽt une Ă©galitĂ© d’intĂ©rĂȘt. Adopter la bonne posture, ne pas se sous-estimer. Si le produit/service suscite l’intĂ©rĂȘt, la startup ne doit pas avoir honte d’ĂȘtre une startup, ne doit pas avoir peur de vendre au bon prix. Il faut faire en sorte que la relation soit profitable dans les deux sens, valoriser les partenariats oĂč le client devient investisseur (Patchwork fou en effectuation).

 

Bonnes vacances

The post La loi de Bigstein ou quand Pirate rencontre Roi appeared first on ekito people.

Catégories: Blog Société

DĂ©veloppeur full stack ? Oui
 mais


Blog d’Ippon Technologies - lun, 08/07/2017 - 08:56

Lorsque nous demandons Ă  un dĂ©veloppeur s’il est full stack, sa rĂ©ponse est gĂ©nĂ©ralement “Oui ! Mais
 plutĂŽt spĂ©cialisĂ© dans 
 telle partie”.

Dans le cadre d’un projet informatique Agile, nous recherchons souvent des dĂ©veloppeurs full stack. Mais, que signifie ce terme et que peut-il apporter au projet ?

Nous allons voir dans un premier temps ce que signifie stack et les raisons mises en avant pour la composition d’une Ă©quipe de personnes full stack. Puis, nous verrons sa mise en place dans le cadre d’un projet informatique au travers d’un exemple.

Qu’est ce qu’une “Stack” ?

Une “stack” est une pile comprenant l’ensemble des couches nĂ©cessaires Ă  la rĂ©alisation d’un projet informatique. Chacun de ces Ă©lĂ©ments ou couche constitue donc la “stack”. On peut par exemple parler de stack technique, si nous ne faisons rĂ©fĂ©rence qu’aux couches techniques d’un projet.

TrĂšs souvent, quand nous parlons de dĂ©veloppeur full stack, nous sommes tentĂ©s de privilĂ©gier uniquement les couches techniques et notamment les couches “front” et “back”. Mais il serait dommage de se limiter aux seuls aspects techniques. En effet, les compĂ©tences dites “soft skills” sont Ă©galement importantes et particuliĂšrement en milieu agile.

Une liste (non exhaustive) d’élĂ©ments composant une “stack” pourrait ĂȘtre :

L’idĂ©e d’une Ă©quipe full stack est donc que chaque membre de l’équipe de dĂ©veloppement puisse intervenir sur chaque couche de la “stack” au sein d’un projet informatique. En consĂ©quence, dans le cas d’un projet Agile (oĂč les dĂ©veloppeurs sont auto-organisĂ©s et ont une responsabilitĂ© plus large que sur un projet cycle en V), un dĂ©veloppeur peut donc :

  • traiter une User Story de bout en bout en cours de sprint (comprĂ©hension fonctionnelle, dĂ©veloppement des diffĂ©rentes parties techniques, etc.) ;
  • relire et valider le travail d’un autre dĂ©veloppeur.
  • intervenir sur les sujets fonctionnels
Avantages supposĂ©s d’une Ă©quipe full stack

Maintenant que nous avons défini les éléments, essayons de comprendre les raisons de ce choix.

Sur le papier, cette mĂ©thode offre beaucoup d’avantages dont les principaux sont :

  • la simplification de l’organisation, car chaque dĂ©veloppeur peut intervenir sur chacun des sujets ;
  • la possibilitĂ© d’accroĂźtre simplement la charge de dĂ©veloppement en augmentant le nombre de dĂ©veloppeurs ;
  • une meilleure implication des dĂ©veloppeurs qui auront en charge des User Stories complĂštes, permettant ainsi une meilleure visibilitĂ© fonctionnelle grĂące Ă  la rĂ©alisation de tĂąches techniques dans des domaines diffĂ©rents (et non pas un seul).

Mais tout cela est-il si simple ? Qu’en est-il en pratique ?

Pour rĂ©pondre Ă  ces questions, il est nĂ©cessaire d’aborder ce qu’on entend par “intervenir sur chaque couche”.

Un dĂ©veloppeur full stack doit pouvoir intervenir sur chacune des couches d’une “stack” ?

Qu’entendons-nous par cette assertion ? Un dĂ©veloppeur doit-il travailler sur chaque sujet ? Si oui, doit-il avoir un niveau de compĂ©tence Ă©quivalent sur chaque couche ?

La rĂ©ponse est non. Il est trĂšs compliquĂ© pour un dĂ©veloppeur d’ĂȘtre compĂ©tent et autonome sur chaque couche.

Quand nous parlons de profil full stack, cela signifie que le dĂ©veloppeur est spĂ©cialisĂ© dans certains domaines, tout en ayant des connaissances sur d’autres sujets. En gĂ©nĂ©ral, nous considĂ©rons un dĂ©veloppeur full stack comme maĂźtrisant au moins 3-4 sujets. Mais cela ne couvre pas l’ensemble des besoins.

AprĂšs avoir analysĂ© ces points, nous comprenons bien les rĂ©ticences des dĂ©veloppeurs Ă  se considĂ©rer full stack car chacun a ses prĂ©fĂ©rences, ses domaines de prĂ©dilection et peut difficilement maĂźtriser toutes les couches d’un projet informatique.

Prenons un exemple

Maintenant que nous avons passé en revue ces différents éléments, intéressons-nous à sa mise en place dans un projet informatique.

Pour illustrer ces propos, prenons l’exemple d’un projet informatique qui dĂ©marre avec la mĂȘme stack que prĂ©cĂ©demment :

Le schĂ©ma ci-dessous permet de visualiser les compĂ©tences d’un dĂ©veloppeur sur l’ensemble de cette stack :

Dans cette situation, nous voyons bien que le développeur est full stack car il a des connaissances dans 90% des sujets et en maßtrise au moins 4.

Cependant, cela ne permet aucunement d’en conclure qu’il est capable d’intervenir sur des sujets pointus dans chaque domaine. Par exemple, il ne sera pas en mesure – ou Ă©prouvera des difficultĂ©s – Ă  rĂ©pondre Ă  une demande complexe concernant la partie front.

Maintenant, imaginons que l’équipe soit composĂ©e de deux dĂ©veloppeurs et que nous souhaitons couvrir, au mieux, tous les sujets du projet. Nous obtiendrions, par exemple, le schĂ©ma suivant (en bleu, le premier dĂ©veloppeur et en jaune le second) :

Dans cette hypothĂšse, les deux dĂ©veloppeurs full stack se complĂštent et la combinaison de leurs compĂ©tences permet de couvrir l’ensemble des besoins du projet. De plus, ces deux dĂ©veloppeurs ont la capacitĂ© de revoir leurs codes respectifs et de monter en compĂ©tence sur des sujets qu’ils maĂźtrisent moins.

Si nous nous projetons sur une équipe plus importante, quel serait le résultat attendu ?

Nous pouvons rĂ©sumer cela par cette phrase : “Pour chaque couche de la stack, avoir au moins deux personnes qui la maĂźtrisent”

Pourquoi deux dĂ©veloppeurs ? Tout simplement pour que l’équipe ne soit pas bloquĂ©e  lorsque l’un des deux est absent (congĂ©s, arrĂȘt, maladie
).

Une digression reste cependant possible. En effet, les besoins existants dans chaque projet informatique n’impliquent pas le mĂȘme niveau de complexitĂ© sur chaque couche. Nous pouvons imaginer dans notre exemple que la partie “API” est trĂšs lĂ©gĂšre et “standard”, donc qu’elle n’aura pas besoin de fortes compĂ©tences. On sera donc moins exigeant vis Ă  vis de l’équipe sur ce point (en terme de niveau de compĂ©tence ou de backup).

Résumé

Comme nous venons de le voir, la composition d’une Ă©quipe full stack est plus complexe qu’associer uniquement des dĂ©veloppeurs dits full stack. Il est nĂ©cessaire d’analyser les spĂ©cialitĂ©s de chaque dĂ©veloppeur qui constitue l’équipe afin d’avoir une cohĂ©rence face aux challenges du projet.

Le risque de n’avoir pas une Ă©quipe aux compĂ©tences suffisamment variĂ©es, est que la rĂ©ponse technique sera potentiellement le fruit de l’expĂ©rience des membres plutĂŽt que la meilleure rĂ©ponse possible. Par exemple, s’il manque un expert UX, les dĂ©veloppeurs pourraient ĂȘtre tentĂ©s de trouver des solutions techniques Ă  un problĂšme d’ergonomie.

Une autre remarque importante : il est difficile d’avoir une organisation idĂ©ale dĂšs les premiĂšres itĂ©rations du projet. N’avoir qu’une personne maĂźtrisant un sujet au dĂ©but peut ĂȘtre un risque acceptĂ© si des montĂ©es en compĂ©tences sont prĂ©vues au sein de l’équipe.

Conclusion

Notons Ă©galement que les derniĂšres annĂ©es montrent une explosion des nouvelles technologies / librairies et qu’il devient de plus en plus difficile pour un dĂ©veloppeur d’ĂȘtre full stack. C’est le cas sur la partie front qui Ă©volue rapidement, mais aussi avec les problĂ©matiques spĂ©cifiques du Big Data qui nĂ©cessite une connaissance pointue sur les outils du domaine et les bonnes pratiques. La spĂ©cialisation sera donc toujours nĂ©cessaire et devrait s’accentuer Ă  l’avenir.

Quant au mot full stack, il serait alors utilisĂ© comme un terme marketing auquel le dĂ©veloppeur essaie de se conformer. En d’autres termes, un dĂ©veloppeur se dĂ©clarant full stack le fait-il plus par obligation ou par choix ?

L’article DĂ©veloppeur full stack ? Oui… mais… est apparu en premier sur Le Blog d'Ippon Technologies.

Catégories: Blog Société

Valiantys earned the certification for Great Place to WorkÂź France !

Le blog de Valiantys - jeu, 08/03/2017 - 14:00

Being pragmatic, curious, outspoken, relaxed and a bit quirky seems to be a good formula for Valiantys. We are pleased to announce that we’ve been officially certified as a Great Place To Work in France in 2017! Great Place to Work is the global authority on building, sustaining, and recognising high-trust, high-performing workplace cultures. They understand that ...

The post Valiantys earned the certification for Great Place to WorkÂź France ! appeared first on Valiantys - Atlassian Platinum Partner.

Catégories: Blog Société

LCC 174 - Interview sur la build avec CĂ©dric Champeau et Arnaud HĂ©ritier - partie 1

Guillaume, Cédric et Arnaud se retrouvent autour du micro pour parler pendant une session marathon de 3h30 du build, de Maven et de Gradle. A premiÚre partie pose les bases: introduction, java 9, performance, gestion de dépendances, cycle de vie

Enregistré le 18 juillet 2017

TĂ©lĂ©chargement de l’épisode LesCastCodeurs-Episode–174.mp3

Interview Ta vie ton Ɠuvre

CĂ©dric Champeau Gradle Inc. Arnaud HĂ©ritier Cloudbees

Liens généraux

Gradle Gradle Enterprise Maven

Guide modules Java 9 :

Liens Gradle

Maven vs Gradle (features) Maven vs Gradle (performance) Migrer vers Gradle Nebula plugins (Netflix) Plugin Go (gogradle) Spring Dependency Management Builds composites Build Cache

DĂ©finition et histoires

Ant

Pour s’échauffer, bon alors, c’est qui le plus fort Gradle ou Maven ? Est-ce que Gradle et Maven ont de la couleur dans la console ? Gradle / Maven: un pitch de 30 secs max pour chacun pour me faire faire mon choix

Support de Java 9

Gradle / Maven: Quand est-ce qu’ils vont supporter Java 9? Et la compilation multi-modules:

Gradle / Maven: Avez-vous eu de l’aide d’Oracle pour faire marcher Java 9? Gradle / Maven: Qu’est-ce que n’est pas prĂȘt pour Java 9?

La performance

C’est quoi le build cache de Gradle ? C’est gratuit ou c’est que dans la version payante ? Parle nous un peu plus de Gradle Enterprise, il y a quoi dedans ? Gradle Entreprise

J’ai fumĂ© la moquette

Quid de l’intĂ©gration avec jshell : je veux Ă©crire mon script de build en Java pas en Groovy (dĂ©solĂ©) ou en Kotlin (dĂ©solĂ©), et surtout que cela soit un fucking REPL (RĂ©mi Forax)

La totale depuis la ML Les projets

Maven, le projet Maven: Pour Maven, qui tient les rĂȘnes du projet ? Maven: La derniĂšre version de Maven est rĂ©cente, avec quelque bugfix (il semble
) La prĂ©cĂ©dente version date de fin 2015 : Maven meurt il Ă  petit feu ? Maven: Qu’est-ce qui fait que Maven n’évolue que trĂšs trĂšs trĂšs peu ? En particulier en terme de performance. Il est mort le projet ou quoi ? Maven: Qui paye le hosting de Maven Central ?

Gradle, le projet, Gradle.inc, l’entreprise Gradle: Gradle Inc propose des guides, des outils pour entreprise : Gradle veut devenir l’outil de build de rĂ©fĂ©rence en entreprise ? Gradle: Groovy va rester le langage principale des scripts Gradle (et Kotlin une alternative) ? Va cohabiter avec Kotlin ? va se voir remplacer par Kotlin ? Gradle: Les derniĂšres versions de Gradle se focalisent beaucoup sur les performances de build. Vers quoi l’outil va s’orienter par la suite ? Gradle: Gradle peut builder des projets en C, des projets Java, Android
. Il y aura un focus sur un Ă©cosystĂšme en particulier ou Gradle va continuer Ă  essayer de tout builder, quitte Ă  se disperser ? Gradle: Quelle est la proportion de projet utilisant Gradle pour construire des projets autres que des projets Java/Android ? Gradle: Gradle est indirectement poussĂ© par Google car utilisĂ© pour construire les applications Android. Gradle est Ă©galement utilisĂ© par Linkedin. Comment ces acteurs influent sur Gradle en terme de fonctionnalitĂ© ?

Et les autres (outils de builds)

Gradle / Maven: Ou en sont les autres, les javascripteurs ? sont-ils toujours Ă  rĂ©inventer x fois la roue ? Ou ont-ils des outils dont Gradle et Maven pourrait s’inspirer ? Gradle / Maven: Qu’est-ce qui a bien pu pousser les javascripteurs Ă  se dire qu’ils pourraient faire un outil intelligent quand ils semblent dĂ©pourvus du moindre bon sens ? Gradle / Maven: Il serait aussi sympa de comparer ces outils a ce qui se fait dans d’autres silos techniques (genre JS avec npm ou autre, C# avec dotnet et NuGet
), voir ce qui est mieux ou moins bien ailleurs. Gradle / Maven: Comment faire du build polyglotte, par exemple avec un mixe de Scala, Kotlin, Groovy, Java, et des sous projets Web (angular cli, webpack, gulp, 
) ? Gradle / Maven: Pourquoi les outils de build apparaissent aussi facilement que les champignons en automne ? Gradle / Maven: Qu’est-ce qui a fait le succĂšs de maven et gradle ? (aussi bien techniquement que d’un point de vue marketing)

La gestion des dépendances

Gradle / Maven: une question plus fondamentale sur gestion de deps vs build : Ă  un moment, dans le monde JS, il y avait une sĂ©paration assez nette entre gestion de dĂ©pendance (avec Bower ou npm je crois) et un outil de build/packaging (genre Gulp il me semble) et des fichiers de conf distincts; maintenant il semble que la mode n’ait pas pris et que npm rĂšgne en maitre et mĂ©lange les 2 sujets dans une meme conf. Est-ce que les experts de build Java pourraient partager leur avis sur la question: pourquoi on mĂ©lange gestion de dĂ©pendances et gestion de build ? Est-ce que c’est vraiment un choix de design ou juste que c’est pragmatiquement suffisant et plus efficace? Gradle / Maven: comment les outils de build permettent de gĂ©rer les dĂ©pendances non-Java ? Tant qu’on reste dans du Java, c’est simple, mais dĂ©s que l’on sort un peu de lĂ  ça se complique (nous on a du natif Windows/Linux, j’imagine que pour les devs Android c’est encore plus compliquĂ©). Peut t’il y avoir des interactions avec des repository non Maven-compliant ? On entend beaucoup parler de Conan pour les artefacts C/C++ ces temps-ci
 Que permet Gradle sur le sujet ? Pouvez-vous nous briefer sur le monde Android qui doit avoir ces problĂ©matiques ?

Le cycle de vie de l’application

Gradle / Maven: Sujet qui pourrait ĂȘtre intĂ©ressant Ă  dĂ©battre : comment est-ce que les deux outils abordent la livraison “en production” ? OĂč est-ce qu’ils s’arrĂȘtent dans leur philosophie (on peut assez facilement imaginer un DSL gradle par exemple pour gĂ©rer les dĂ©ploiements) ? En particulier, quid des environnements oĂč les plateformes de production n’ont pas accĂšs Ă  internet (et donc pas accĂšs aux dĂ©pĂŽts officiels et pas de miroir disponible/accessible, j’ai vu ça chez les opĂ©rateurs tĂ©lĂ©com). La solution mise en place ici, c’est livraison sous forme d’iso/de cd sur lesquels il y a toutes les dĂ©pendances, et cette iso est montĂ©e comme un repo Ă  partir duquel on installe la solution. Et Ă  partir de lĂ , viennent d’autres problĂšmes d’ordre juridiques : comment est pensĂ©e la gestion des licences, en particulier en ce qui concerne les dĂ©pendances transitives ? Gradle / Maven: Un peu liĂ© : quelles diffĂ©rences dans les deux outils pour la construction d’applis orientĂ©es serveur vs. appli orientĂ©es client ?

Nous contacter

Faire un crowdcast ou une crowdquestion Contactez-nous via twitter https://twitter.com/lescastcodeurs sur le groupe Google https://groups.google.com/group/lescastcodeurs ou sur le site web https://lescastcodeurs.com/ Flattr-ez nous (dons) sur https://lescastcodeurs.com/ En savoir plus sur le sponsoring? sponsors@lescastcodeurs.com

 

Catégories: Blog Individuel

MythBuster: Apache Spark ‱ Épisode 1: Parsing d’une requĂȘte SQL

Spark est en Ă©volution constante et maintient un rythme soutenu de sorties de releases, en tĂ©moigne la derniĂšre version en date, la 2.2. Dans cette sĂ©rie d’articles, nous allons revenir ensemble sur diffĂ©rentes mĂ©caniques actuellement en place au sein de cet outil et essayer d’en comprendre le fonctionnement.

code {
background-color: #efefef;
font-family: Courier New, Courier,Lucida Sans Typewriter, Lucida Typewriter, monospace;
}
Préface Spark 2 et le projet Tungsten

Depuis la version 2.0, Spark s’appuie sur un moteur d’exĂ©cution retravaillĂ©, nommĂ© Tungsten. Celui-ci embarque avec lui son lot d’amĂ©liorations, et confirme la volontĂ© des contributeurs de rendre Spark toujours plus performant et accessible.

En particulier, le gros des efforts de dĂ©veloppement s’est concentrĂ© sur l’amĂ©lioration des DataFrames (et plus rĂ©cement les Datasets) qui permettent, entre autres, de manipuler de la donnĂ©e Ă  partir de requĂȘtes SQL classiques. L’enjeu de ces amĂ©liorations est d’offrir aux dĂ©veloppeurs une API simple et haut-niveau avec le minimum de contrepartie en termes de performances.

Dans cette optique, une des Ă©volutions du moteur Tungsten semble avoir fait faire un grand pas en avant Ă  Spark puisque, sous rĂ©serve d’utilisation des DataFrames, sans aucune modification de code entre Spark 1.6 et Spark 2.0, les performances pourraient ĂȘtre multipliĂ©es par 10. Cet exploit serait en majeur parti du Ă  une technique de gĂ©nĂ©ration du code Ă  la volĂ©e afin d’accroĂźtre la vitesse d’exĂ©cution
 Rien que ça.

DĂ©mystification

Je ne sais pas pour vous, mais pour nous, « plan d’exĂ©cution », « gĂ©nĂ©ration de code Ă  la volĂ©e », « moteur d’optimisation », etc. sont des concepts dont on a tous entendu parler sans trop vraiment savoir ce qui se cache derriĂšre. Et quand on y pense, on pourrait mĂȘme dire la mĂȘme chose de Spark, non ?

C’est suite Ă  cette rĂ©flexion que nous avons dĂ©cidĂ© de dĂ©cortiquer le code source de Spark et d’en extraire l’essence, afin de comprendre en dĂ©tail ce qu’il se passe sous le capot
 Pour cela, nous allons construire ensemble un moteur capable de partir d’une simple requĂȘte SQL sous forme de String et de l’exĂ©cuter, en s’appuyant sur le code source de Spark.

Nous chercherons à répondre aux questions suivantes :

  • Comment peut-on passer d’une requĂȘte SQL Ă  une structure exploitable directement avec du code ?
  • Comment est construit et optimisĂ© un plan d’exĂ©cution ?
  • Quel est l’intĂ©rĂȘt de gĂ©nĂ©rer du code et comment faire ?

Ce sera Ă©galement l’occasion d’apprĂ©hender ensemble certaines fonctionnalitĂ©s de Spark.

Pour cela, nous allons dĂ©couper cet article en 3 parties : la premiĂšre traitera du parsing d’une requĂȘte, la deuxiĂšme de la construction d’un plan d’exĂ©cution physique, la derniĂšre partie mettra l’accent spĂ©cifiquement sur la gĂ©nĂ©ration de code.

L’intĂ©gralitĂ© du code que nous allons rĂ©aliser est prĂ©sent sur le GitLab d’OCTO : que les plus curieux d’entres-vous n’hĂ©sitent-pas Ă  y faire un tour avoir une vision dĂ©taillĂ©e du fonctionnement de notre implĂ©mentation !

Un sous-ensemble du langage SQL

La gĂ©nĂ©ration de code sera le point d’arrivĂ©e de cette sĂ©rie d’article mais nous allons voir qu’avant cela, il y a un certain nombre d’Ă©tapes par lesquelles nous devons passer. La premiĂšre consiste Ă  transformer une requĂȘte SQL sous forme de String en quelque-chose d’un peu plus pratique Ă  manipuler avec du code.

L’objectif ici n’Ă©tant pas de rĂ©implĂ©menter Spark mais uniquement de comprendre son fonctionnement, nous n’allons pas chercher Ă  supporter l’ensemble de la version 2011 de SQL. Le langage SQL que nous allons implĂ©menter va se restreindre aux contraintes suivantes :

  • Seulement des requĂȘtes de type SELECT avec des clauses FROM et JOIN seront interprĂ©tĂ©es
  • Seul deux types seront supportĂ©s, Ă  savoir NUMBER et TEXT
  • Les mots clĂ©s devront ĂȘtre en majuscules et les identifiants (nom des tables, des colonnes, etc.) en minuscules
  • Les donnĂ©es des tables seront situĂ©es dans des fichiers CSV dont le nom doit ĂȘtre le mĂȘme que celui de la table

Concernant le dernier point, notons que Spark possĂšde une API particuliĂšre pour dĂ©crire les sources de donnĂ©es (qui seront considĂ©rĂ©es comme des tables au sein des requĂȘte SQL) et qu’il est possible d’ajouter ses propres sources, mais ce n’est pas quelque-chose que nous allons couvrir ici.

InterprĂ©tation d’une requĂȘte SQL

La premiĂšre Ă©tape de notre pĂ©riple va ĂȘtre de transformer une String en quelque chose de programmatiquement utilisable


Un peu de théorie


Cette transformation se déroule en deux étapes réalisées par deux composants :

  • Le Lexer : il dĂ©crit l’ensemble des mots clĂ©s qui dĂ©finit une requĂȘte SQL (SELECT, WHERE, FROM, etc.) et les localise dans une String donnĂ©e en entrĂ©e. Il transforme ainsi une String en une liste d’Ă©lĂ©ments qui composent notre lexique. Ces Ă©lĂ©ments sont ce que l’on appelle des Tokens. Les mots qui ne font pas partie de ce lexique sont identifiĂ©s par le token Literal s’il s’agit d’une valeur (un nombre ou un texte entre guillemets), et sinon, il s’agit d’un Identifier.
  • Le Parser : lĂ  oĂč le Lexer a une approche lexicale, le Parser a une approche sĂ©mantique : c’est lui qui va donner un sens Ă  la requĂȘte SQL Ă  partir des tokens identifiĂ©s par le Lexer. Pour cela, la liste de Tokens va ĂȘtre convertie en une structure un peu particuliĂšre, l’AST (ou Abstract Syntax Tree)


L’AST est un arbre dont le rĂŽle est de reprĂ©senter une requĂȘte SQL parsĂ©e, en hiĂ©rarchisant les Token identifiĂ©s par le Lexer.

Par exemple, lorsque l’on Ă©crit SELECT column, il faut comprendre que le terme column s’applique au terme SELECT. Le premier est donc un argument du second. Dans l’AST, le SELECT se trouve au dessus du column.

Deux catĂ©gories d’AST sont Ă  distinguer :

  • La catĂ©gorie Expression qui va correspondre aux opĂ©rations que l’on rĂ©alise sur les lignes (comme par exemple les prĂ©dicats appliquĂ©s au niveau des clauses WHERE et ON de nos requĂȘtes) ;
  • La catĂ©gorie Relation qui va dĂ©terminer la maniĂšre dont les lignes sont produites (dans notre cas, via les FROM et JOIN, mais on peut aussi penser aux SELECT si l’on avait implĂ©mentĂ© la notion de sous-requĂȘte).

En deux mots : la Relation correspond Ă  l’origine de la donnĂ©e, et l’Expression Ă  ce que l’on en fait.

Notre implémentation ! Nos classes Lexer et Parser

Chacun des types de Token identifiables par le Lexer est reprĂ©sentĂ© par une case class Scala qui Ă©tend le trait Token. Le rĂŽle de la classe Lexer va donc ĂȘtre simplement d’associer certains motifs d’une String Ă  la sous classe de Token correspondante.

L’idĂ©e n’Ă©tant pas d’Ă©crire un parser qui supporte la totalitĂ© du langage SQL, nous allons utiliser les Parser Combinators qui suffisent amplement dans notre cas.

def select: Parser[Select] = positioned { "SELECT" ^^ { _ => Select() } }

Exemple d’un Parser Combinator qui permet de parser le mot clĂ© SELECT en un Token Select() (qui est une case class Scala)

Pour une explication détaillée du fonctionnement des Parsers Combinators, nous redirigeons le lecteur vers la documentation de cette librairie.

Comme leur nom l’indique, il est possible d’associer plusieurs Parser Combinators ensemble, chacun Ă©tant en charge d’un mot clĂ©. Nous sommes ainsi capables d’identifier tous les termes que l’on souhaite au sein d’une String, ce en itĂ©rant sur chacun des mots de la String et en appliquant tous nos Parser Combinators.

L’ensemble des rĂšgles ainsi implĂ©mentĂ©es dans notre code est regroupĂ© dans notre objet Lexer prĂ©sent dans Lexer.scala. Token.scala contient l’ensemble des Tokens pris en compte par notre Lexer.

Liste des case classes qui dérivent de Token

Le trait AST

L’objet Parser s’appuie Ă©galement sur les Parser Combinators pour construire notre AST.

Si l’implĂ©mentation des diffĂ©rents parsers peut sembler lĂ©gĂšrement absconse au premier abord, il n’est pas nĂ©cessaire d’en comprendre les dĂ©tails pour poursuivre la lecture.

L’utilisation des Parser Combinators constitue nĂ©anmoins une pratique courante pour le parsing en Scala.

Cette fois, grĂące au travail du Lexer, ce ne sont plus des String que l’on identifie, mais des Token, ce qui simplifie le travail et la comprĂ©hension du programme.

Pour pouvoir construire un arbre Ă  partir de ces Tokens, on ne peut plus se contenter d’appliquer l’ensemble de nos Parser Combinators Ă  nos Ă©lĂ©ments (comme nous l’avions fait dans le Lexer). Nous allons devoir appliquer de façon rĂ©cursive, et dans un certain ordre nos diffĂ©rents Parser Combinator.

Par exemple, nous allons commencer par le parser Select, qui lui mĂȘme attend en paramĂštre un nom de colonne, un From, et, Ă©ventuellement, un Where. Chacun de ces paramĂštres correspondent Ă©galement Ă  des Parser qui attendent, eux aussi, d’autres paramĂštres. De façon rĂ©cursive, nous allons ainsi construire notre arbre syntaxique (le Parser Combinator correspondant aux Expressions est un peu particulier, cf. Pour aller plus loin).

Le Select est donc un type d’AST qui attend en paramĂštre :

  • Une liste d’expressions qui correspondent Ă  l’ensemble des projections dĂ©crites juste aprĂšs le terme SELECT
  • Une liste de relations qui correspondent Ă  l’ensemble des tables sources dĂ©crites juste aprĂšs le terme FROM
  • Éventuellement une derniĂšre expression qui correspond aux filtres (ou prĂ©dicats) dĂ©crits juste aprĂšs le terme WHERE (sachant qu’il est possible d’appliquer plusieurs filtres en utilisant les expressions AND ou OR)

Hiérarchie des case classes qui dérivent de AST

RĂ©capitulatif

Pour résumer, le parsing se déroule donc en deux étapes :

  • Le lexing de la String en une Seq[Token] grĂące Ă  l’objet Lexer qui va valider le vocabulaire utilisĂ© au sein de la requĂȘte SQL
  • Le parsing de la Seq[Token] en un AST grĂące Ă  l’objet Parser qui va valider la sĂ©mantique de la requĂȘte SQL

Les deux Ă©tapes qui constituent le parsing

Et du cÎté de chez Spark ?

Les auteurs de Spark ont quant à eux pris le parti de déléguer cette fastidieuse étape de parsing à un célÚbre outil qui mature depuis plus de 20 ans cette problématique : ANTLR !

Je pense qu’on l’a tous dĂ©jĂ  croisĂ© quelque-part


A l’inverse de bon nombre de projets Scala, les dĂ©veloppeurs de Spark ont dĂ©cidĂ© d’utiliser Maven en lieu et place de SBT pour gĂ©rer le build. Juste avant la compilation de Spark, c’est donc le plugin Maven d’ANTLR qui va gĂ©nĂ©rer les classes nĂ©cessaires pour rĂ©aliser le parsing (ce que nous avons fait manuellement en implĂ©mentant le Lexer et Parser ci-dessus) en se basant sur la grammaire dĂ©finie ici.

La traduction en case classes est quant-Ă -elle rĂ©alisĂ©e ici par l’AstBuilder.

Pour aller plus loin
 Recursive Descent Parser

La premiĂšre implĂ©mentation basĂ©e sur les Parser Combinator que nous avions rĂ©alisĂ©e Ă©tait assez naĂŻve, ce qui a eu pour consĂ©quence des embĂȘtantes StackOverflowException
 Tiens-donc.

En effet : bien que relativement simple, la grammaire que nous avons dĂ©finie est rĂ©cursive (par exemple, un terme d’une addition peut lui-mĂȘme ĂȘtre une addition) ce qui n’est pas supportĂ© de base par les Parser Combinators. De ce fait, nous avons dĂ» revoir notre implĂ©mentation et mettre en place un Recursive Descent Parser dont le principe est trĂšs bien dĂ©crit ici. Pour nous aider dans cette tĂąche, nous nous sommes Ă©normĂ©ment inspirĂ©s de cette classe disponible sur GitHub.

Apache Calcite

Le parsing de requĂȘte SQL est une problĂ©matique rĂ©currente : en plus des SGBDR communs, nombre de solutions Big Data s’appuient aujourd’hui sur le langage SQL pour manipuler les donnĂ©es.

Apache Calcite est une initiative d’Apache dont l’objectif est de rĂ©soudre diffĂ©rentes problĂ©matiques liĂ©es Ă  la conception de base de donnĂ©es (SGBDR ou NoSQL), dont – entres autres – le parsing du SQL.

Par exemple, Apache Hive s’appuie sur Calcite pour le parsing du SQL (mais Ă©galement pour l’optimisation des requĂȘtes, mais ça, c’est pour une autre fois
).

A suivre


A partir de notre String de dĂ©part qui Ă©tait difficilement utilisable, nous avons pu, Ă  l’aide de notre Parser et de notre Lexer, en tirer un AST beaucoup plus exploitable programmatiquement et qui dĂ©crit l’objectif de la requĂȘte SQL.

Nous allons voir dans le prochain article comment transformer cet AST en une nouvelle structure qui va cette fois-ci dĂ©crire la maniĂšre dont la requĂȘte va s’exĂ©cuter
 Rendez-vous la semaine prochaine !

Articles suggested :

  1. Une analyse géographique des articles de Medline
  2. Compte rendu du Spark Summit 2016

Catégories: Blog Société

DĂ©veloppement Agile et Craft

Vous ĂȘtes dĂ©veloppeur mobile pour un journal d’information bien connu. Les articles paraissent sur un site web et l’application Android correspondante est utilisĂ©e par des centaines de milliers d’utilisateurs. Elle permet de rĂ©agir sur les articles, et les utilisateurs ne s’en privent pas : c’est le thĂ©Ăątre de dĂ©bats d’un haut niveau Ă©motionnel, si ce n’est orthographique.

Mais un matin, aucune rĂ©action postĂ©e depuis l’application ne paraĂźt plus sur le site. Les avis dĂ©favorables s’accumulent sur le Play Store :

« Impossible de rĂ©agir depuis l’application. Aucune rĂ©action envoyĂ©e depuis l’application ne parvient aux modĂ©rateurs, alors que les rĂ©actions envoyĂ©es depuis le site passent sans problĂšme. » –RaphaĂ«l H.

« Je suis abonnĂ© mais aucun des messages que je dĂ©pose avec mon smartphone ne s’affiche lorsque je commente l’actualitĂ©… » –Michel K.

« […] Censure des commentaires n’allant pas dans le sens des articles, je me suis donc dĂ©sabonnĂ©… […] » –Adrien V.

Cette situation demande d’agir vite et bien. C’est l’occasion d’illustrer une approche de dĂ©veloppement qui mĂȘle agilitĂ© et savoir-faire (craftsmanship).

Voici le comportement de l’application en matiĂšre de commentaires :

  • L’application permet de poster un commentaire en rĂ©action Ă  l’article lui-mĂȘme (indicateur response à false)
  • Elle permet de rĂ©pondre au commentaire d’un autre utilisateur (indicateur response à true)

Avant de vous distraire de votre tĂąche en cours, votre leader technique a pris le temps d’analyser l’anomalie : l’application ne poste pas les commentaires correctement. Le mapping entre l’indicateur response et la valeur envoyĂ©e Ă  l’API est incorrect. C’est un « if » qui a Ă©tĂ© codĂ© Ă  l’envers.

Le code en question rĂ©vĂšle l’erreur de mapping concernant la valeur du paramĂštre responseFlag attendu par l’API.

sendReaction(message, item, response);
public void sendReaction(String message, String answeredItem, boolean response) {

    int responseFlag;
    if (response) responseFlag = 0;
    else responseFlag = 1;
                    
    api.postReaction(message, answeredItem, responseFlag);
}
Agilité

Compte tenu de l’importance du bug, vous mettez de cĂŽtĂ© vos dĂ©veloppements en cours. Vous committez vos changements et vous passez sur une nouvelle branche issue de la version de production.

Votre premier rĂ©flexe est d’ouvrir le test unitaire (TU) du code en question. Qui n’existe pas. Damned. Le bug aurait pu ĂȘtre repĂ©rĂ© si un test avait Ă©tĂ© rĂ©digĂ© lors du dĂ©veloppement initial.

Le code est dans une Activity Android. Vous Ă©valuez l’investissement que constitue la rĂ©daction d’un nouveau test unitaire dans cette situation, et vous prĂ©fĂ©rez laisser le TU de cĂŽtĂ© le temps de produire un correctif dĂ©montrable afin de rassurer votre client.

Vous appliquez le correctif qui consiste Ă  inverser les branches du if. Dans l’immĂ©diat, vous privilĂ©giez la correction du bug par rapport au refactoring.

public void sendReaction(String message, String answeredItem, boolean response) {
 
    int responseFlag;
    if (response) responseFlag = 1;
    else responseFlag = 0;
                    
    api.postReaction(message, answeredItem, responseFlag);
}

Vous testez le correctif sur votre poste de dĂ©veloppement, puis vous publiez le code sur une branche du dĂ©pĂŽt de votre organisation. Le leader technique valide vos changements, vous faites le merge dans la branche d’intĂ©gration.

Votre serveur d’intĂ©gration continue met automatiquement Ă  disposition du reste de l’Ă©quipe une version de recette. Votre Ă©quipe pratique le dogfooding : c’est quand les membres de l’Ă©quipe sont les premiers utilisateurs de leur propre application. Cette pratique permet de confirmer l’absence de rĂ©gression dans des conditions rĂ©elles d’utilisation. Vous montrez le correctif Ă  votre client qui confirme la correction.

Jusqu’Ă  maintenant, vous avez respectĂ© les valeurs agiles :

  • Vous avez privilĂ©giĂ© l’interaction avec votre leader technique pour prendre en compte rapidement un bug sensible
  • Vous avez favorisĂ© la remise en condition opĂ©rationnelle de votre application en laissant de cĂŽtĂ© le refactoring et la documentation
  • Vous avez collaborĂ© avec votre client pour corriger l’anomalie sans vous attarder sur la nature du dĂ©veloppement (bug ou Ă©volution)
  • Vous avez adaptĂ© vos prioritĂ©s suite Ă  la remontĂ©e de l’anomalie au lieu de continuer vos dĂ©veloppements en cours
Craftsmanship

Et maintenant ? Le processus minimal est respectĂ©, du point de vue de votre client, vous pourriez donc livrer une nouvelle version hotfix de votre application et passer au ticket suivant, mais votre travail n’est pas terminĂ©. Dans la mĂ©thode sendReaction, au moins un refactoring vous dĂ©mange. Et votre beau correctif n’est toujours pas testĂ© unitairement.

Compte tenu de la simplicité du correctif, vous pouvez tout reprendre du début.

Vous commencez par écrire un test automatisé. Ici, le plus approprié est un test unitaire qui vérifie la logique du if.

Mais avant de pouvoir Ă©crire ce test unitaire, le code doit ĂȘtre repensĂ©. La classe impactĂ©e par le correctif est fortement couplĂ©e avec le framework Android qui est difficile Ă  simuler dans un test unitaire. Vous avez deux solutions :

  • Mettre en place le framework Robolectric pour simuler le framework Android dans votre TU
  • Appliquer le pattern Passive View pour sortir la logique du if dans une classe sĂ©parĂ©e, qui serait testable facilement car non dĂ©pendante du framework

Vous choisissez la Passive View car vous pensez que Robolectric ralentirait l’exĂ©cution de vos tests, et Ă  cause du dĂ©lai des mises Ă  jour de Robolectric suite Ă  celles du SDK Android.

DÚs que le test passe, vous en profitez pour transformer le paramÚtre response en enum, petit refactoring qui vous démangeait :

public void sendReaction(String message, String answeredItem, CommentType commentType) {

    api.postReaction(message, answeredItem, commentType.getApiFlag());
} 
enum CommentType {

    INITIAL("0"), ANSWER("1");

    private String mApiFlag;

    CommentType(final String apiFlag) {
        mApiFlag = apiFlag;
    }

    public String getApiFlag() {
        return mApiFlag;
    }
}

Vous adaptez votre test unitaire au changement de signature de la méthode sendReaction().

Ensuite vous faites en sorte que votre dĂ©veloppement puisse ĂȘtre repris et maintenu facilement par un autre dĂ©veloppeur, grĂące Ă  une sĂ©ance de revue de code. En support Ă©crit, vous prĂ©parez une pull request dĂ©taillĂ©e sur GitHub dont la description rappelle :

Le besoin fonctionnel Correction d’un bug au niveau des rĂ©actions La spĂ©cification technique
  • Extraction de la logique dans une classe dĂ©couplĂ©e
  • Inversion du sens du if
Le scénario de test
  1. Brancher l’application sur un environnement de recette
  2. Poster un commentaire sur un article
  3. Poster une réaction à un autre commentaire
  4. Observer qu’ils sont bien reçus par le backend et que leur type est correct

Ce niveau de dĂ©tail par Ă©crit permet de garder une documentation Ă©crite et indexĂ©e au sujet du correctif au cas oĂč un autre besoin impacterait ce pĂ©rimĂštre de code.

NB : l’idĂ©al serait d’intĂ©grer la documentation au code afin de la rendre plus « vivante » et pour qu’elle puisse Ă©voluer avec le code. Mais ce type d’approche est coĂ»teux Ă  mettre en place sur du code existant ; vous laissez donc de cĂŽtĂ© ce chantier pour l’instant.

Quelques heures plus tard, la version corrigĂ©e est publiĂ©e sur le Play Store, certains utilisateurs l’ont installĂ©e, et les premiĂšres rĂ©actions des utilisateurs arrivent sur les articles. Vous retrouvez enfin leur douce prose, les trolls, la crĂ©ativitĂ© orthographique.

Ici vous avez appliqué votre savoir-faire et respecté les valeurs Craft :

  • Vous avez soignĂ© votre code en le refactorant aprĂšs avoir appliquĂ© un correctif
  • En ajoutant un test automatisĂ©, vous avez garanti la non-rĂ©gression pour Ă©viter de corriger toujours les mĂȘmes bugs. Ainsi vous pourrez continuer d’ajouter de la valeur.
  • En documentant votre code et en le montrant Ă  un autre dĂ©veloppeur, vous avez favorisĂ© l’appropriation collective du code
  • Vous avez Ă©tabli une relation de partenariat avec votre client en prenant la responsabilitĂ© de soigner l’aspect technique (tests unitaires, refactoring) au delĂ  d’un correctif minimal
Conclusion

À partir d’une situation vĂ©cue, dans le contexte du dĂ©veloppement mobile, cet article illustre l’application des valeurs agiles et craft.

Dans le contexte d’un bug sensible, cette approche s’appuie sur les valeurs agiles pour prendre en compte les attentes du client en termes de rapiditĂ© de mise au point d’un correctif.

Elle s’appuie aussi sur les valeurs craft pour permettre Ă  la base de code de rester saine et comprĂ©hensible par les autres dĂ©veloppeurs, prĂ©sents et futurs.

Références
Catégories: Blog Société

Your next app will be an assistant

ekito people - lun, 07/31/2017 - 08:00

For some years now, embedded technologies have been easily affordable (both in price and simplicity of control). You can look at any book store and find every month a magazine with fun stuff about domotic. “yeah, you can light on your house with your raspberry pi”. Yes, your house can be a good subject to make for IOT things. For most of those kits, you have to make it all – from hardware to software.

Since last year, we began to see “home assistant” boxes like Amazon Alexa or Google Home, giving full power and control for any connected stuff. For developers, the message is quite clear : here is an SDK to extend those assistant technologies. With such power at finger tips, everyone wants its “Jarvis” at home (see Mark Zuckerberg’s Jarvis).

The next challenge for IT makers is not to make a gorgeous web application, a beautiful mobile app or make your house lighting with dots. The real thing is to bring technology where it can really solve problems, and where it is difficult to bring technology! This new way of interacting with systems (vocal conversations & commands), gives control in a different way : you don’t need any more physical device in your hand… but a vocal device somewhere around you

Catégories: Blog Société

Créer des instances AWS qui ont accÚs à Internet sans IP publique avec Terraform

Il nous est souvent demandé : Comment est-ce que je fais pour créer des instances AWS qui ont accÚs à internet mais sans IP publique ?

Tout d’abord, qu’est ce qu’une IP publique? Une IP publique est une adresse IP joignable sur internet. A contrario des adresses IP privĂ©es (dĂ©crites dans la RFC 1918) qui elles ne sont pas visibles de l’extĂ©rieur du rĂ©seau.

 

L’architecture Amazon à mettre en place

 

 

SchĂ©ma de l’architecture Ă  mettre en place

 

Tout d’abord nous avons besoin d’un VPC (Virtual Private Cloud) (1) qui va hĂ©berger nos diffĂ©rents sous-rĂ©seaux (subnets). Un VPC est une brique AWS nous permettant ici de gĂ©rer les Ă©lĂ©ments rĂ©seaux de notre infrastructure.

Pour avoir un accĂšs Ă  internet, il faut poser une Internet Gateway (2). L’Internet Gateway est le composant AWS permettant de lier les Ă©lĂ©ments d’un VPC Ă  Internet.

Ensuite nous avons un Subnet “publique”  (3) : toutes les instances / objets Ă  l’intĂ©rieur seront routĂ©es sur internet.

Nous allons ensuite mettre en place deux Subnets dit “privĂ©s” (4) : les instances / objets Ă  l’intĂ©rieur ne seront pas directement routĂ©es sur internet, ils auront accĂšs Ă  internet sans ĂȘtre accessible depuis l’extĂ©rieur.

Enfin, pour permettre à des instances d’accùder à internet sans avoir d’IP publiques, nous allons utiliser une NAT Gateway (http://docs.aws.amazon.com/fr_fr/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html).

Le concept “Network Address Translation” (NAT), permet de transposer des adresses rĂ©seaux, souvent privĂ©es, en d’autres adresses. C’est un concept rĂ©guliĂšrement utilisĂ© pour des composants d’un rĂ©seau privĂ© pour avoir accĂšs Ă  internet sans ĂȘtre accessible (adressable) depuis l’extĂ©rieur (c’est le fonctionnement des box que nous avons tous chez nous).

La NAT Gateway se pose dans le subnet publique et dispose d’une adresse publique, en l’occurrence un Elastic IP (EIP) chez AWS. Il reste Ă  s’intĂ©resser au routage de la NAT Gateway aux instances des subnets privĂ©s.

Le Subnet publique aura sa propre RouteTable (routeur chez AWS). Celle-ci aura une route qui fera sortir tout le traffic sortant (0.0.0.0/0) vers l’Internet Gateway.

Les Subnets privĂ©s auront une autre RouteTable, celle-ci aura aussi une route qui permettra de faire sortir le traffic sortant (0.0.0.0/0) mais cette fois vers la NAT Gateway et non vers l’Internet Gateway.

Pour implĂ©menter cela, nous allons utiliser Terraform qui va dĂ©ployer l’architecture sur AWS. Pour en savoir plus sur Terraform et son fonctionnement : https://blog.octo.com/deployer-son-infrastructure-google-cloud-platform-grace-a-terraform.

DĂ©ploiement de notre infrastructure

Commençons par exporter les variables d’environnements nĂ©cessaire (credentials et rĂ©gion) :

export AWS_ACCESS_KEY_ID=<XXXXXXXXXXXXXX>
export AWS_SECRET_ACCESS_KEY=<XXXXXXXXXXXXXX>
export AWS_DEFAULT_REGION=<XXXX>

Nous avons besoin de récupérer la région courante, pour cela nous allons utiliser un Datasource Terraform (https://www.terraform.io/docs/providers/aws/d/region.html) :

data "aws_region" "region" {
 current = true
}

Créons notre VPC :

resource "aws_vpc" "my_vpc" {
  cidr_block = "10.0.0.0/16"

 tags {
    Name = "my_vpc"
  }
}

Ensuite nous allons créer tous les composants nécessaire au Subnet publique :

resource "aws_subnet" "public_subnet" {
  vpc_id = "${aws_vpc.my_vpc.id}"
  cidr_block = "10.0.0.0/24"
  availability_zone = "${data.aws_region.current.name}a"

  map_public_ip_on_launch = true
  tags {
    Name = "public subnet"
  }
}

Dans la configuration du subnet, nous pouvons voir que pour le champs availability_zone nous utilisons le datasource de la region.

Nous spĂ©cifions aussi le champs map_public_ip_on_launch Ă  true. Cela permet Ă  toutes les instances lancĂ©es dans ce subnet d’avoir par dĂ©faut une IP publique.

Pour le dĂ©ploiement de notre NAT Gateway nous avons besoin de deux objets : l’IP publique et la NAT Gateway en elle-mĂȘme :

resource "aws_eip" "nat_eip" {
  vpc = true
}

resource "aws_nat_gateway" "nat" {
  allocation_id = "${aws_eip.nat_eip.id}"
  subnet_id     = "${aws_subnet.public_subnet.id}"
}

Nous posons donc la NAT Gateway dans le subnet publique. Petit dĂ©tail, une NAT Gateway quand on la pose dans le Subnet dispose aussi d’une IP privĂ©e. Celle-ci est trĂšs rarement utilisĂ©e, nous verrons juste aprĂšs dans la RouteTable que nous prĂ©fĂ©rons utiliser l’ID de la NAT Gateway.

Sur cette premiĂšre partie, il nous reste Ă  mettre en place le routage :

resource "aws_route_table" "public_routetable" {
  vpc_id = "${aws_vpc.vpc.id}"
  tags {
    Name = "Public Routetable"
  }
}

resource "aws_route" "public_route" {
  route_table_id         = "${aws_route_table.public_routetable.id}"
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = "${aws_internet_gateway.internet_gateway.id}"
}

resource "aws_route_table_association" "public_subnet_a" {
  subnet_id      = "${aws_subnet.public_subnet.id}"
  route_table_id = "${aws_route_table.public_routetable.id}"
}

Passons maintenant Ă  la deuxiĂšme partie, la crĂ©ation des subnets privĂ©s. Nous allons crĂ©er deux subnets, un dans l’Availability Zone A et un autre dans l’Availability Zone B.

resource "aws_subnet" "private_subnet_a" {
  vpc_id = "${aws_vpc.my_vpc.id}"
  cidr_block = "10.0.1.0/24"
  availability_zone = "${data.aws_region.current.name}a"
  tags {
    Name = "private subnet A"
  }
}

resource "aws_subnet" "private_subnet_b" {
  vpc_id = "${aws_vpc.my_vpc.id}"
  cidr_block = "10.0.2.0/24"
  availability_zone = "${data.aws_region.current.name}b"
  tags {
    Name = "private subnet B"
  }
}

Nous allons passer à la derniÚre partie : la configuration du routage de la partie privée. Il faut donc créer la RouteTable, les association et bien entendu la route qui dirige vers la NAT Gateway.

resource "aws_route_table" "private_routetable" {
  vpc_id = "${aws_vpc.vpc.id}"
  tags {
    Name = "private Routetable"
  }
}

resource "aws_route_table_association" "private_subnet_a" {
  subnet_id      = "${aws_subnet.private_subnet_a.id}"
  route_table_id = "${aws_route_table.private_routetable.id}"
}

resource "aws_route_table_association" "private_subnet_b" {
  subnet_id      = "${aws_subnet.private_subnet_b.id}"
  route_table_id = "${aws_route_table.private_routetable.id}"
}

resource "aws_route" "nat_route" {
  route_table_id         = "${aws_route_table.private_routetable.id}"
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = "${aws_nat_gateway.nat.id}"
}

Nous allons crĂ©er deux outputs Terraform pour permettre d’indiquer en sortie les subnets dans lesquels il faut poser les instances.

output "private_subnet_a_id" {
  value         = "${aws_subnet.private_subnet_a.id}"
}

output "private_subnet_b_id" {
  value         = "${aws_subnet.private_subnet_b.id}"
}

Le code est disponible ici : https://github.com/mathieuherbert/aws-terraform/blob/master/vpc_with_nat_gateway

Conclusion

Nous avons vu que permettre Ă  des instances d’avoir Ă  accĂšs Ă  internet sans ĂȘtre accessible demande plusieurs objets. Ces objets peuvent ĂȘtre compliquĂ©s Ă  manipuler dans un premier temps.
Il existe une implĂ©mentation plus historique et qui n’est plus conseillĂ©e par AWS : la NAT Instance. Celle-ci demande de manager soi-mĂȘme son instance et sa disponibilitĂ© (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_NAT_Instance.html ).

Concernant la disponibilitĂ© de la NAT Gateway, celle-ci est dĂ©pendante de la disponibilitĂ© de la zone de son Subnet d’hĂ©bergement. Pour assurer la disponibilitĂ© sur une rĂ©gion au globale, une NAT Gateway par zone de disponibilitĂ© est nĂ©cessaire avec des impacts sur le routage.

Articles suggested :

  1. AWS re:Invent 2015 : retour sur les annonces et compte-rendus
  2. GĂ©rer dynamiquement l’accĂšs Ă  ses environnements avec HAProxy et le SNI
  3. Le DÉFI DES BOG’OPS : notre recette du Team Spirit

Catégories: Blog Société

Superviser mon application Play! avec Prometheus

logo

Il nous semble clair que l’industrie de l’informatique s’est finalement mis d’accord sur trois choses :

  1. Nous avons besoin de faire du code de qualité
  2. Il faut intégrer le code de maniÚre continue
  3. Il faut superviser ce que nous installons

Les pratiques du craftsmanship, en particulier le refactoring, couplĂ©es Ă  un ensemble d’outils de test permettent d’affronter le premier. La construction de pipelines d’intĂ©gration avec des usines comme Jenkins, GoCD ou TravisCI permettent d’attaquer le deuxiĂšme. Cependant, la supervision, la situation n’est pas aussi claire. Du coup, il existe une grande variĂ©tĂ© de fonctionnalitĂ©s (stack) pour superviser la JVM, suivre des mĂ©triques mĂ©tiers, gĂ©rer des alertes, etc. La popularisation des architectures distribuĂ©es (dont les microservices) n’a fait qu’empirer la problĂ©matique.

Pour résoudre tous ces problÚmes, nous avons choisi une stack composée de Prometheus, CAdvisor et Grafana et nous allons vous montrer comment les utiliser pour superviser une application de site web basée sur Play! framework.

Le choix de la stack de supervision

Finalement, nous avons terminĂ© notre application Play!. Nous avons fait nos tests et notre chaĂźne d’intĂ©gration continue et l’application est mĂȘme installĂ©e dans l’environnement de UAT (User Acceptance Testing). C’est Ă  ce moment-lĂ  que nous rĂ©alisons que nous n’avons pas pensĂ© Ă  la supervision !

AprĂšs une rapide recherche, nous trouvons qu’il existe en fait deux modĂšles de communication : le push et le pull. Dans le modĂšle push, l’application monitorĂ©e envoie rĂ©guliĂšrement ses mĂ©triques Ă  l’outil de monitoring. Typiquement, il existe entre l’application et l’outil de monitoring un agent intermĂ©diaire qui est chargĂ© de la collection des mĂ©triques. Dans le modĂšle pull, c’est l’outil de monitoring qui connaĂźt les applications monitorĂ©es et les requĂȘte Ă  une frĂ©quence spĂ©cifique.

En approfondissant notre recherche nous trouvons plusieurs alternatives :

positionnement

Les alternatives 1. Telegraf + InfluxDB

C’est une stack basĂ©e sur une architecture de push.

Telegraf est un agent qui récupÚre et exporte des métriques vers un systÚme de stockage comme InfluxDB. InfluxDB est une base de données de type time series utilisée pour le stockage de métriques.

Ces deux outils sont en gĂ©nĂ©ral utilisĂ©s avec Kapacitor. Il fait le pilotage des donnĂ©es et la gestion des alertes. Pour exemple, Kapacitor permet d’Ă©valuer une mĂ©trique dans une fenĂȘtre de 5 ms, la compare avec un seuil puis envoie une alerte sur Slack.

InfluxDB

2. Statsd + Graphite

Également, cette stack est basĂ©e sur une architecture de push.

Statsd est un agent rĂ©seau (UDP et TCP) qui permet d’Ă©couter des statistiques et de les envoyer vers un autre systĂšme comme Graphite.

Graphite est capable de stocker des donnĂ©es de type time series (c’est-Ă -dire qu’elles sont ordonnĂ©es dans le temps) et fournit Ă©galement un langage de requĂȘtage. Il prĂ©sente une approche similaire Ă  celui de Telegraf et InfluxDB. L’ajout des informations complĂ©mentaires est basĂ©e sur la crĂ©ation des nouvelles mĂ©triques. Les deux mĂ©triques suivantes permettent de compter le nombre de requĂȘtes en succĂšs ou en erreur pour le path /login

stats.api-server.login.get.200 -> 93
stats.api-server.login.get.500 -> 45

Un exemple de l’intĂ©gration de graphite se montre comme suit

graphite-grafana

3. Nagios

Cette stack est basée sur un modÚle de pull.

Nagios est un outil spĂ©cialisĂ© surtout sur le monitoring de l’infrastructure. Il est donc plutĂŽt utilisĂ© comme une alternative à sensu. Il comporte un nombre important de plugins mais il ne fait pas le stockage des donnĂ©es, nous devons donc recourir Ă  d’autres outils pour gĂ©rer la persistance.

Le monitoring d’une application basĂ©e sur la JVM (comme Play!) se fait typiquement en utilisant JMX ou en s’intĂ©grant avec statsd.

perfdata

4. Prometheus

Encore une autre stack qu’utilise une approche de pull.

Prometheus est un systĂšme de monitoring et d’alerting. L’approche pull nous intĂ©resse Ă©normĂ©ment parce que nous pouvons maĂźtriser les donnĂ©es mĂ©tier que nous voulons rendre publiques dans les applications de monitoring. En fait pour Prometheus, la seule contrainte imposĂ©e Ă  l’application monitorĂ©e est d’ĂȘtre capable de produire du texte avec HTTP. Avec cet outil, il est possible d’ajouter des ensembles de clĂ©s-valeurs pour rendre le monitoring plus dynamique. La mĂ©trique suivante est donc parfaitement valide :

http_request_duration_seconds_bucket{le="0.02",method="GET",path="/assets/:file",status="2xx"} 23

Une vision Ă  plus haut niveau sur l’intĂ©gration d’une application avec Prometheus est montrĂ©e dans l’image suivante :

prometheus-grafana

Cet outil va rester notre choix pour le reste de cet article.

La visualisation

Cependant, il nous reste Ă  choisir l’outil pour la visualisation de nos mĂ©triques. Les alternatives les plus utilisĂ©es sont :

  • Kibana + Timelion. Kibana est l’outil de visualisation par dĂ©faut dans Elasticsearch. Timelion permet l’intĂ©gration de timeseries dans Kibana. Ensemble, ces outils aident Ă  la visualisation mais surtout Ă  l’analyse et l’exploration des donnĂ©es au travers de multiples dimensions.
  • Grafana. Cet outil a Ă©tĂ© conçu pour faciliter la visualisation de dashboards complexes basĂ©es sur des sources timeseries.

Dans notre exemple, nous n’avons pas besoin d’explorer les donnĂ©es et nos dashboards ne sont pas destinĂ©s Ă  un utilisateur final. Ce qui nous intĂ©resse est de pouvoir afficher les mĂ©triques, vĂ©rifier l’Ă©tat de santĂ© de notre application et dans le futur, pouvoir crĂ©er des alarmes. Grafana sera par consĂ©quent l’outil choisi pour la visualisation de nos mĂ©triques.

Les mĂ©triques exposĂ©es par l’application basĂ©e sur Play! Framework

Pour pouvoir exposer les mĂ©triques depuis notre application, il nous faut importer une librairie cliente. Nous avons choisi ce client non officiel pour Scala car il s’adapte un peu mieux Ă  la philosophie compile time safe de Scala, mais nous aurions Ă©galement pu utiliser le client officiel. Pour l’utiliser dans le projet il suffit de l’ajouter dans le fichier build.sbt

libraryDependencies += "org.lyranthe.prometheus" %% "client" % "0.9.0-M1"
L’exposition des mĂ©triques Prometheus va rĂ©guliĂšrement demander Ă  l’application (toutes les 15 secondes par dĂ©faut) ses nouvelles mĂ©triques. Nous devons donc fournir une maniĂšre de crĂ©er les mĂ©triques que nous allons calculer. Nous appelons cette classe un MetricBuilder. Ce builder permet la crĂ©ation de tous les objets qui vont stocker la valeur courante pour chaque mĂ©trique (Counter, Gauge, Histogram et autres). Chaque mĂ©trique doit s’enregistrer auprĂšs d’un Registry pour pouvoir ĂȘtre requĂȘtĂ©e le moment venu avec un appel au outputText. L’implĂ©mentation de ces objets est fournie par le client de Prometheus, il suffit de les configurer et les instancier.
class PrometheusMetricBuilder @Inject()(lifecycle: ApplicationLifecycle, implicit val prometheusRegistry: Registry) { 
  def buildOutputText: String = prometheusRegistry.outputText // prints all metric values
  ... // other metrics
}

Nous devons exposer une url avec toutes les valeurs courantes pour chaque mĂ©trique. Nous allons le faire depuis un contrĂŽleur en utilisant l’implĂ©mentation du Registry injectĂ©e dans notre Builder.

@Singleton
class PrometheusMetricsController @Inject()(metricBuilder: PrometheusMetricBuilder) extends Controller {
  def metrics = Action {
    val samples = new StringBuilder()
    val writer = new WriterAdapter(samples)
    writer.write(metricBuilder.buildOutputText)
    writer.close()

    Result(
      header = ResponseHeader(200, Map.empty),
      body = HttpEntity.Strict(ByteString(samples.toString), Some("text/plain"))
    )
  }
}

Nous pouvons exposer ce traitement dans le path que nous souhaitons. L’url /metrics semble ĂȘtre une bonne idĂ©e. Rajoutons-lĂ  Ă  notre fichier routes.

GET     /metrics                    controllers.PrometheusMetricsController.metrics

Nous n’allons pas rentrer dans le dĂ©tail des types de mĂ©triques, le but Ă©tant de rechercher une solution rapide pour les premiĂšres mĂ©triques de notre nouvelle application. Nous proposons alors les trois mĂ©triques suivantes :

Les mĂ©triques 1. Le nombre de visites dans l’application

Supposons que nous voulions monitorer le nombre absolu de visiteurs. Notre objectif est de pouvoir nous donner une idĂ©e du succĂšs de notre site. Celui-ci est un nombre qui augmentera toujours. Pour crĂ©er cette mĂ©trique il suffit de construire une instance de type Counter et l’enregistrer auprĂšs d’un Registry de mĂ©triques fourni par le client de Prometheus.

@Singleton
class PrometheusMetricBuilder @Inject()(lifecycle: ApplicationLifecycle, implicit val prometheusRegistry: Registry) {
  ...
  val counter = Counter(metric"play_requests_total", "Total requests.").labels().register
  ...
}

Ensuite, nous pouvons l’utiliser dans notre contrĂŽleur.

@Singleton
class HomepageController @Inject()(builder: PrometheusMetricBuilder) extends Controller {
  def index = Action {
    builder.counter.inc()
    Ok(views.html.index("Your new application is ready."))
  }
}
2. Le nombre d’utilisateurs connectĂ©s

Le nombre d’utilisateurs connectĂ©s est une mĂ©trique qui doit pouvoir s’incrĂ©menter et se dĂ©crĂ©menter par rapport au nombre de connexions et dĂ©connexions, voire des abandons de page. Prometheus appelle ce type de composant un Gauge. Nous devons Ă©galement Ă©couter le hook (l’envoi du message) de finalisation de l’application pour prendre en compte les utilisateurs qui ferment leur navigateur. Pour cela nous avons une instance de l’ApplicationLifecycle qui nous donne un callback lors de l’arrĂȘt de l’application. Nous allons procĂ©der de maniĂšre similaire Ă  la mĂ©trique prĂ©cĂ©dente.

@Singleton
class PrometheusMetricBuilder @Inject()(lifecycle: ApplicationLifecycle, implicit val prometheusRegistry: Registry) {
  ...
  val gauge = Gauge(metric"play_current_users", "Actual connected users").labels().register
  lifecycle.addStopHook { () => Future.successful(gauge.dec()) }
}

Par contre, la logique de ce contrÎleur est plus complexe car nous devons augmenter la valeur lors du login, et la réduire lors du fermeture de la session.

@Singleton
class SessionController @Inject()(builder: PrometheusMetricBuilder) extends Controller {
  def login = Action {
    builder.gauge.inc()
    Ok("Logged in ...")
  }
  def logout = Action {
    builder.gauge.dec()
    Ok("Logged out!")
  }
}
3. Le temps de réponse par url

Le temps de réponse est typiquement analysé grùce aux échantillons pris pour chaque route disponible dans notre application. Dans la terminologie de Prometheus, ce type de métrique est appelé un histogramme.

Pour effectuer l’Ă©chantillonnage, nous devons crĂ©er un filtre qui met Ă  jour un composant de type Histogram avec les informations suivantes:

  • La mĂ©thode HTTP
  • Le path
  • Le status de la rĂ©ponse
  • Le temps de rĂ©ponse

Il suffit d’ajouter le composant dans notre PrometheusMetricBuilder :

@Singleton
class PrometheusMetricBuilder @Inject()(lifecycle: ApplicationLifecycle, implicit val prometheusRegistry: Registry) {
  ...
  val httpRequestLatency =
    Histogram(metric"http_request_duration_seconds",
      "Duration of HTTP request in seconds")(httpHistogramBuckets)
      .labels(label"method", label"path", label"status")
      .register
  ...
}

Nous pouvons Ă©crire ce filtre comme suit :

class PerformanceFilter @Inject()(implicit
                                  val mat: Materializer,
                                  builder: PrometheusMetricBuilder,
                                  executionContext: ExecutionContext
                                ) extends Filter {
  ...
  def apply(nextFilter: RequestHeader => Future[Result])(
    requestHeader: RequestHeader): Future[Result] = {
    val timer = Timer()
    val future = nextFilter(requestHeader)
    getRouteDetails(requestHeader) match {
      case Some(details) =>
        future.onComplete {
          time(timer) { statusCode =>
            builder.httpRequestLatency.labelValues(
              details.method,
              details.route,
              statusCode)
          }
        }

      case None =>
        // rien Ă  faire ici
    }
    future
  }
}

Une fois notre application exécutée, testons le lien localhost:9000/metrics pour pouvoir vérifier les valeurs de nos deux métriques.

play_current_users 0.0
play_requests_total 1.0
http_request_duration_seconds_bucket{le="1.0E-4",method="GET",path="/",status="2xx"} 0
http_request_duration_seconds_bucket{le="0.005",method="GET",path="/metrics",status="2xx"} 0
http_request_duration_seconds_bucket{le="0.01",method="GET",path="/metrics",status="2xx"} 1

Nous avons un code capable d’exposer des mĂ©triques, mais il faut maintenant se connecter à Prometheus, CAdvisor et Grafana.

Tester en local avec docker-compose

Pour Ă©viter de tout installer en local, nous fournissons un repository Github avec la configuration initiale basĂ©e sur docker-compose qui vous permettra de dĂ©marrer toute l’infrastructure que nous venons de dĂ©crire :

  • Un container pour Prometheus
  • Un container pour CAdvisor
  • Un container pour l’application avec le framework Play!
  • Un container pour Grafana

Pour tout dĂ©marrer, il suffit d’exĂ©cuter :

docker-compose up -d

Une fois terminé, vous devriez avoir quatre containers :

Containers

Ces differents containers sont liés de la maniÚre suivante :

Docker-engine

CAdvisor

Le Container Advisor permet d’exposer la consommation des resources des container docker. Vu que nous allons utiliser Pometheus et d’autres composants dans docker, CAdvisor semble une trĂšs bonne idĂ©e car il est nativement capable d’exposer des mĂ©triques sur la consommation rĂ©seau, mĂ©moire et disque vers Prometheus. Si nous allons à  http://localhost:8080/containers/ nous allons voir un rĂ©sultat similaire Ă  celui-ci :

Metrics

La configuration de Prometheus

La configuration de Prometheus est basĂ©e sur un fichier nommĂ© prometheus.yml dans lequel nous devons spĂ©cifier les endpoints de ce que nous allons monitorer. Chacun peut avoir sa propre configuration contenant le target (combinaison hĂŽte et port), le path url oĂč l’application expose ses mĂ©triques, l’intervalle d’Ă©valuation et d’autres options si nĂ©cessaire.

global:
  scrape_interval:     15s
  evaluation_interval: 15s
  external_labels:
    monitor: 'monitoring-play-app'
scrape_configs:
  - job_name: 'prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['cadvisor:8080']
  - job_name: 'playframework-app'
    scrape_interval: 5s
    metrics_path: '/metrics'
    static_configs:
      - targets: ['play-app:9000']

Vu que nous lions les conteneurs entre eux, il est possible d’utiliser le nom de notre container en tant qu’adresse IP. L’exemple prĂ©cĂ©dent permet de monitorer trois services :

  • CAdvisor. Qui tourne dans un container appelĂ© cadvisor sur le port 8080.
  • notre application Play!. De maniĂšre similaire, notre application est disponible Ă  l’url play-app:9000.

Pour vĂ©rifier que nos targets sont bien prises en compte il nous suffit de vĂ©rifier directement sur Prometheus Ă  l’adresse http://localhost:9090/targets. Ici, nous utilisons localhost pour parler avec le container parce nous sommes sur linux. Vous obtenez le mĂȘme rĂ©sultat si vous utilisez Docker for mac ou Docker for windows.

Targets

Il est Ă©galement possible de requĂȘter nos mĂ©triques sur http://localhost:9090/graph. Dans cette page nous pouvons :

  • VĂ©rifier que nos mĂ©triques sont bien prises en compte.
  • VĂ©rifier que les mĂ©triques se modifient dĂšs que nous requĂȘtons notre application Play!
  • Tester des opĂ©rations de regroupement (sommes, moyennes, et autres)
 check
  • PrĂ©visualiser nos mĂ©triques
 graph-current

Cependant, ceci n’est pas vraiment un outil de visualisation et pour cela nous avons besoin d’un logiciel spĂ©cialisĂ©.

Grafana

La suite de visualisation de mĂ©triques Grafana va nous permettre de suivre en temps rĂ©el les mĂ©triques de notre application. L’interface est accessible depuis http://localhost:3000.

Nous allons créer une data source pour pouvoir interroger le service de Prometheus, afin de lier nos métriques à la visualisation de Grafana.

Source

Ensuite, nous devons ajouter un dashboard qui affichera les mĂ©triques exposĂ©es des targets de Prometheus. Heureusement, dans le repository Github nous fournissons un dashboard prĂȘt Ă  l’emploi. Il permet la visualisation des mĂ©triques envoyĂ©es par notre application et ceux de CAdvisor. Il suffit alors d’importer le fichier Grafana_Dashboard.json. Une fois installĂ©, nous avons un panel qui montre le rĂ©sultat de nos mĂ©triques de visites et d’utilisateurs connectĂ©s.

data

Nous devons avoir également un histogramme avec le temps de réponse des url de notre application :

response time

De plus, grùce au CAdvisor nos avons des métriques de consommation de mémoire, processeur et disque de tous nos containers :

CPU

Et voilà, nous avons finalement un outil de monitoring intégré à notre application.

Conclusion

Nous avons abordé les différences entre les modÚles push et pull pour la communication avec les outils de monitoring, puis nous avons comparé quelques outils et finalement nous avons choisi Prometheus.

Ensuite, nous avons montré comment exposer des métriques sur un endpoint depuis une application basée sur Play! framework. Finalement nous avons montré le résultat final avec un docker-compose contenant entre autre un dashboard Grafana pour le suivi en temps réel des métriques.

Nous pouvons conclure qu’au final, les outils qui permettent d’avoir des mĂ©triques sont maintenant assez simples d’utilisation.

Quelques problĂšmatiques restent toujours ouvertes comme par exemple la maniĂšre d’intĂ©grer de multiples instances de notre application ou l’intĂ©gration d’un systĂšme d’alertes. Nous aborderons ces sujets lors d’un prochain article.

Catégories: Blog Société

JFrog: A new partner for Valiantys

Le blog de Valiantys - jeu, 07/27/2017 - 14:00

It’s with great pleasure that we announce the launching of our partnership with JFrog, who are the editors of Artifactory, Bintray, Mission Control and Xray. Many of our clients are already familiar with JFrog through Artifactory, a universal Artifact Repository Manager. Why JFrog you may ask? For over 10 years, Valiantys has chosen to focus its efforts around Atlassian products – ...

The post JFrog: A new partner for Valiantys appeared first on Valiantys - Atlassian Platinum Partner.

Catégories: Blog Société

Prise en main de Leaptest, solution de testing

Le blog Webnet - jeu, 07/27/2017 - 11:00
Dans la longue liste des outils de tests, Selenium reste la rĂ©fĂ©rence. Mais qui dit testeur ne dit pas forcĂ©ment dĂ©veloppeur, et plusieurs Ă©diteurs proposent des solutions accessibles aux non-codeurs. Leaptest est un outil basĂ© sur Selenium, qui permet d’élaborer des scĂ©narios de tests complexes, en utilisant un Ă©diteur graphique, appelĂ© Studio. Le Studio permet […]
Catégories: Blog Société

GopherCon Denver : Retour sur la conference Go

http://blog.xebia.fr/wp-content/uploads/2017/07/gophercon_logo_main.png

Les 12,13,14 et 15 Juillet, a eu lieu Gophercon à Denver (Colorado, USA). La conférence la plus importante sur le langage Go.

  • La sĂ©ance du 12 a Ă©tĂ© dĂ©diĂ©e aux ateliers.
  • Les sĂ©ances du 13 et 14 ont Ă©tĂ© dĂ©diĂ©es aux confĂ©rences.
  • Le 15 (Community Day), Ă©tait l’occasion pour la communautĂ© Go de s’exprimer au travers de lightning talks, de tables rondes et de groupes de travail sur des projets spĂ©cifiques (par exemple dep, kops, le langage Go etc). Un espace Ă©tait rĂ©servĂ© pour des communautĂ©s spĂ©cifiques comme gopherdata (tensorflow, gonum, machinebox, pachyderm) ou gobot afin de faire connaitre leurs avancĂ©es ou laisser les participants programmer des « bots » ou « drones » en utilisant des outils Go. À la fin du dernier jour, il y a eu une table ronde sur la diversitĂ© dans la communautĂ© Go.

J’ai eu l’opportunité d’y aller. Et en plus d’une communautĂ© trĂšs inclusive et ouverte, j’ai trouvĂ© des confĂ©rences de qualitĂ©, des projets en croissance et des personnes de tous horizons, ouvertes et bienveillantes.

Dans cet article je vous propose un aperçu de ce que vous avez pu manquer (ou pas, si vous avez eu la chance d’y participer) durant les deux jours de confĂ©rences. Il pourra Ă©galement vous servir de grille de lecture des quelques talks, dont l’information se trouve ici et les videos ici.

Premier jour de conférences Go Reliability and Durability at Dropbox

Tammy Butow, dĂ©veloppeuse d’infrastructure chez Dropbox, a ouvert les sessions avec un retour d’expĂ©rience de l’utilisation du Go chez Dropbox.
 

Elle a racontĂ© qu’ils ont commencĂ© Ă  utiliser le langage pour ses promesses de simplicitĂ© et de performance. Ils ont conçu et dĂ©veloppĂ© plusieurs systĂšmes avec Go et ont obtenu de trĂšs bon rĂ©sultats avec l’intĂ©gration de plusieurs Ă©quipes. La courbe d’apprentissage des nouveaux dĂ©veloppeurs a Ă©tĂ© relativement basse, mais ils ont encore quelques problĂšmes de « race conditions » dans la gestion des donnĂ©es, qui reste encore trĂšs difficile Ă  gĂ©rer.

Tammy a expliquĂ© qu’ils ont une mĂ©thodologie de « chaos engineering » qui consiste Ă  introduire des erreurs sur des noeuds de l’application distribuĂ©e. Cette pratique nous rappelle celle utilisĂ©e par Netflix avec Simian Army.

The Future of Go

Dans ce talk Russ Cox a lancĂ© la conception de Go 2.0. Il a dĂ©crit pourquoi passer Ă  Go 2. L’idĂ©e n’est pas d’abandonner Go 1.X sinon de commencer la conception et la construction de cette nouvelle version parallĂšlement afin de rĂ©soudre les problĂšmes de mise Ă  l’Ă©chelle. L’idĂ©e est de respecter la promesse de compatibilitĂ© de Go et de ne pas fragmenter l’Ă©cosystĂšme.

Ensuite, il a confirmé que le cycle de releases de Go ne changera pas.

Finalement, il a formalisĂ© une mĂ©thodologie pour l’intĂ©gration des fonctionnalitĂ©s sur Go. Il s’agit de la maniĂšre dont la communautĂ© travaille aujourd’hui :
1. Accumuler de l’expĂ©rience sur Go au travers de son utilisation
2. Identifier et expliquer un problĂšme
3. Proposer une solution
4. Implémenter, évaluer et affiner la solution
5. DĂ©ployer la solution en prod.

Il n’est pas nĂ©cessaire qu’une seule personne fasse toutes les Ă©tapes.

Les conversations pour Go 2.0 ont commencĂ© Ă  ce moment-lĂ . Il faut commencer Ă  rĂ©diger des rapports d’expĂ©riences et Ă  imaginer les nouvelles fonctionnalitĂ©s de Go 2.0

A Go Programmer’s Guide to Syscalls

Cette fois, Liz Rice nous a aidĂ© Ă  comprendre les appels systĂšme (syscalls). Elle a dĂ©veloppĂ© en direct un outil strace (un outil de traçage d’appels systĂšme) en Go et nous l’avons testĂ© avec un simple « hello world ». 

Valuable Lessons in Over-Engineering the Core of Kubernetes kops

Kris Nova nous a appris une leçon trĂšs utile : il faut savoir rester simple. Dans le dĂ©veloppement de l’outil kops (kubernetes), son Ă©quipe a investi beaucoup de temps en essayant de construire un interprĂ©teur de yaml, qui est devenu un langage en soit trĂšs difficile Ă  maintenir, tester et peu pratique pour les utilisateurs (il Ă©tait trĂšs facile d’introduire des bugs dans la construction du cluster). C’est pour ça, qu’ils ont pris la dĂ©cision d’abandonner ce « nouveau langage » et de se focaliser sur une API qui permet aux utilisateurs de kops de dĂ©velopper leur cluster en utilisant Go.

Go Anti-Patterns

Il y a eu aussi l’espace pour le craft en Go. Edward Muller nous a rappelĂ© certaines mauvaises pratiques ou « bad smells » trĂšs communes, dont :

  • Le syndrome du tiny package
  • Premature exportation ou l’exposition des structures niveau package
  • Le mauvais nommage de package et la creation d’un package « utils » Ă  dĂ©faut d’une meilleure idĂ©e de nommage
  • CrĂ©er des structures pour stocker les options ou les configurations
  • L’excĂšs des pointeurs
  • Les if-then-else au lieu des « happy-paths »
  • L’utilisation d’un interface {}, etc.
DeuxiÚme jour de conférences Understanding Channels

Dans la premiĂšre keynote du deuxiĂšme jour, Kavya Joshi nous a appris l’implĂ©mentation des go-channels. Nous avons commencĂ© par examiner comment il y a eu un compromis entre simplicitĂ© et performance, oĂč la simplicitĂ© a Ă©tĂ© sacrifiĂ©e et la performance est assurĂ©e pour le runtime scheduler qui permet aux threads du systĂšme d’exploitation, de rester « unblocked » et d’optimiser l’utilisation de mĂ©moire.

My Journey to Go

Ashley Macnamara nous a Ă©mues aux larmes avec cette deuxiĂšme keynote, oĂč elle nous a racontĂ© comme elle est devenue dĂ©veloppeusse Go et dĂ©veloppeur Ă©vangĂ©liste, aprĂšs une carriĂšre dans la photographie.
Un exemple Ă  suivre pour toutes les personnes qui veulent devenir dĂ©veloppeurs ou qui sont en reconversion dans l’informatique. Elle nous a Ă©galement rappelé qu’il n’est pas nĂ©cessaire d’ĂȘtre Rob Pike, Dave Cheney ou Jessie Frazelle pour contribuer Ă  Go.

Advanced Testing with Go

Michell Hachimoto nous a prĂ©sentĂ© de bonnes pratiques pour tester nos dĂ©veloppements Go, sur les niveaux d’une mĂ©thodologie de tests et des maniĂšres d’Ă©crire un code plus stable.

Parmi les pratiques abordées il a mentionné :

  • Tests unitaires pilotĂ©s par des donnĂ©es
  • La creation des « Tests Helpers » afin d’encapsuler la gestion d’erreurs et le code de rĂ©fĂ©rence
  • L’execution des tests des sub-processus en condition rĂ©el et au travers de « Mocks »
The Fallacies Of Distributed Computing

Michael Hausenblas nous a parlé des « 8 fallacies » (idées fausses) décrites par Peter Deutsch et comment les aborder sur nos projets Go.

  • Le rĂ©seau est fiable
  • Le temps de latence est nul
  • La bande passante est infinie
  • Le rĂ©seau est sĂ»r
  • La topologie du rĂ©seau ne change pas
  • Il y a un et un seul administrateur rĂ©seaux
  • Le coĂ»t de transport est nul
  • Le rĂ©seau est homogĂšne.
The New Era of Go Package Management

Finalement, Sam Boyer nous a parlĂ© d’un nouvel outil pour la gestion de dĂ©pendances de Go : dep. Cette outil  est pensĂ© pour devenir le nouveau standard Go.

Conclusion

Cette expĂ©rience a Ă©tĂ© trĂšs enrichissante. C’Ă©tait une Ă©dition riche tant en qualitĂ© des talks qu’en variĂ©tĂ© des sujets, projets et activitĂ©s.

En attendant la prochaine Ă©dition, nous pouvons continuer Ă  contribuer aux projets open source et Ă  aider concevoir la prochaine version de Go!

Goodies

Catégories: Blog Société

Agile transformation with Henrik Kniberg @OCTO Technology

Henrik Kniberg is Agile/Lean coach at Crisp in Stockholm, speaker at international conferences and author of popular books about XP, Scrum, Kanban and Lean from the Trenches. Working primarily with Spotify and LEGO, he enjoys helping companies succeed with both the technical and human sides of software development.

After his presentation at USI, Henrik had accepted our invitation to answer some questions from our clients in their transformation journey towards Agile. This event is facilitated by Sergey Larionov, Agile Coach at OCTO Technology, and made in a breakfast format, where clients can come for 2 hours before starting their day of work. The event was filmed and full video can be found on this link (user/password : hkniberg/the_nextmorningafter_USI).

How did you get to Agile?

“Entirely by accident
” :)

Looking for a way to run Henrik’s own organizations as an entrepreneur and manager, and searching for diverse sources of inspiration, he discovers some frameworks such as Scrum or eXtreme Programming and by implementing them step-by-step learns that it is way better than waterfall. Being a consultant, he started helping clients to apply these methods as well. He started to write about what he learnt, generated more consultant engagement and it became viral.

 

What brought you to Spofity?

Spotify is the most known example of Henrik’s work on Agile culture and Product Ownership.

One day, after delivering recurrent talk, what he use to do between consultant engagements, Henrik got a call from Spotify, a small start-up at that time build by a group of students from a Swedish university, who participated on his talk. They were trying to apply Scrum and had a “growth pain” and asked Henrik to come and help dealing with that.

 

What about Agile journey?

The journey is quite different depending on where you come from. For big organization with many people Agile means simplifying, allowing teams autonomy, removing waste and overloaded structure. For startups, it is the opposite, Agile serves to add structure where there is a significant growth with too much entrepreneurial chaos, although not becoming bureaucratic. When there are few teams it is easy, when it comes to 6-9 teams, the books don’t give you answers anymore to questions such as synchronization between teams or how to organize people into teams, etc. Applied experience in different contexts, use case study and try some patterns may bring you these answers.

 

How did you get into LEGO?

LEGO is Henrik’s second flagship project. They got inspired by his work at Spotify, notably by Scaling Agile, and asked him to create an environment where people are happy and doing a good job. Agile might help to do it. LEGO was using SAFe framework and they needed help.

 

Why LEGO have decided to implement SAFe?

The Product department has already been Agile, but other departments such as Sales, HR, Marketing, used a lot of Waterfall method, which worked well, until one day they understood that the world is moving too fast and they had too many failures. Since then, they have gone crazy with innovation by allowing teams full autonomy. LEGO was running out of money and almost went bankrupt because of loosing control of everything. They made up changes and became super focused as a company by aligning everything that everybody does with the high level goals of the company.

Meanwhile, there was a disconnect between portfolio and budgeting systems based on 2 years cycle and software development teams trying to be very fast. They had a middle management layer running in meetings all the day, updating spreadsheets and sending emails. Over several years they figured out that it doesn’t make sense, not effective nor motivating. Until one day middle management took trainings about Agile and SAFe and got inspired. They were not sure if it would work, but maybe it’s worth trying. And they started from experiment. Experiments are a lot easier to sell than organizational change. LEGO asked Henrik, who is framework neutral, helping them trying these experiments. They tried to put 120 people together and do sprint planning with single backlog, introduce cross-functional teams, etc. and it kind of worked. Then they focused on removing waste in this new functioning.

Starting from 80% couple of years ago, nowadays LEGO is using only about 20% of SAFe. In conclusion, SAFe is a framework based on Agile & Lean principles, it is just too detailed. At scaling there is no “one-size-fits-all”, but there are some patterns. All frameworks are saying the same thing: use Agile principles, work with teams, do the planning together if you have dependencies, plan synchronisation meetings where all the teams come together for an integrated demo where everyone can learn, then make changes.

“All the frameworks are saying the same thing, it is just a different level of detail”.

Look at frameworks and case studies, steal the best ideas, but avoid the trap believing that a framework is going to answer all your questions.

 

How to switch from command & control to the Agile mindset?

Those who behave in command & control mode are used to top-down way of working, but once they tried another approach they would switch the mindset, because often their behaviour wasn’t intrinsic, but the result of the system they are living inside.

When the system changes, behaviour changes.

Of course for those people who love control and get scary by uncertainty, they may not fit into Agile. It doesn’t mean that they don’t fit for the organization, but they don’t fit for the part of the organization where there is uncertainty. For repeatable actions with minor changes and low complexity you probably don’t need Agile. But for uncertain, changing and complex world, Agile will definitely help you. Although command & control people would not be happy in this new working mode, would not deliver a good work and will resist. Better to find for them another environment.

Starting a transformation, don’t judge people. Just go, but be observant. For people, who do not understand, help them to understand, listen to them, but if you notice that someone is clearly unhappy help him to find a place where his skills would fit better.

 

How to deal with top management who wants 100% control, but also convinced by need of Agility to welcome continuous rapid change?

Start by asking, “What do you want to control?”, “Why do you need Agile?”, “How did the last project work out?”, “Did it work out as planned?”, “Are you happy with the results?”. If the previous project worked perfectly, you don’t need Agile. But often all you have in the waterfall is illusion of control.

We can control the budget, number of teams and the deadline, but not what exactly the product is going to look like. It doesn’t make sense to lock the product, instead focus on the desired outcome and what problem we want to solve.

Mostly you will find out that Agile gives a better control. Every sprint is a real-time control point to look at something that runs and works, to see what failed (after one sprint instead of at the end of the project), and make changes. Agile increases the control and removes the illusion of control.

 

How do you go to maintenance mode after product has been developed? What do we do with an Agile team when the main functional scope has been finished?

In waterfall mode once the project team has done their project, it goes to a low-cost maintenance team.

Giving the project from Agile team to maintenance team is not a good idea, as it is a risky and costly action. No matter how much project team documented, the most knowledge is in the heads of developers. It takes time to understand the product, why it was designed this way, writing documents, spending time on explaining. A better solution would be to move the Agile team on another product while delivering value and keeping maintenance of a previous one.

One of common patterns is, once the main functional scope is delivered, the team just starts working on a new product B, and fix what is needed from previous product A. Whether adding it when needed in a current sprint, whether plan a specific sprint for maintenance, which would impact the A product fixing reactivity, but would let the team focus on product B and make it move faster. Basic Agile architecture is stable teams, stable backlogs, just decide which team pulls from where.

Another pattern is a common single backlog, where teams just pull from it to make sure the highest value is delivered by following the development. Gather teams, introduce them the context, explain the priorities and let them choose their own team backlog items. If there are a large number of people you may need a Chief Product Owner to prioritize between different Product Owners and take decisions on common priority.

Only you can decide which pattern makes sense in your context. If you are not sure, then just try, and if it doesn’t work, try something else.

 

How can we do continuous delivery in multiple teams when we have dependencies?

One of very powerful patterns is integration cadence. It is a moment, every week @Spotify or every month @LEGO, when everyone, who works on the same product, gets together. It creates intrinsic motivation to collaborate in preparing demos and space to fail for innovation. It also helps to solve a typical Agile problem of abused autonomy by introducing a hard constraint, where no matter what, the team has to show the results. In addition, it forces them to communicate with dependent teams on potential delays and take decision on planned scope.

How to deal with dependencies between Agile and waterfall teams?

It is exactly the same situation at LEGO where Digital solutions is an Agile team and Corporate IT is a waterfall one. A pattern that helped here was to visualize dependencies and invite teams to see it, let the people speak to each other. It happens every month at LEGO during Planning meeting (see also Program Increment at SAFe) where teams collaborating in optimizing planning taking in account mutual dependencies.

Visualize, optimize, remove the bottleneck and organize yourself to minimize dependencies.

Here is the presentation shown during the event.

 

Do you have a transformation template to standardize the working process?

If your way of working is pre-defined, what happens with continuous improvement? In the case when the team wants to make an improvement they would have to pass by phase of negotiation with others or do it secretly. Any of these cases generates frustration. Standardization is greatly overrated. Some people may become rebellious and hide the way they work. It breaks trust and goes against Agile, as it is about “Individuals and Interactions Over Processes and Tools” (one of Agile values).

When people ask for standardization leading to the common way of work, there is usually a reason for that. First of all, ask why they want it and what need do they want to satisfy. Usually the need is valid, but solution is not good.

For instance, their need is to go faster and standardization is the proposed answer. Let’s think about other options to go faster. By making teams work, whatever way they want, they continuously improve and in consequence move fast. Another example is to reveal problems. Within the team, the retrospective or any other tool of continuous improvement can help to visualize impediments and let team members find most appropriate solutions. In dependent teams make them discuss together and collectively find a way to solve problems. The standardization could happen if it answers to a real need. In case of generic problems, for instance, when different teams are using various versioning control system or none, that causes absence of a simple way to integrate the whole product, multiple teams are working on, and to test it in a continuous way. Bring them together, do root cause analysis and choose a system that they all hate the least. Let the problem drive the standardization and keep it on the minimum level to not slow down the rate of innovation.

How do you deal with the feeling of loosing the ability to do everything in start-up, which is growing and multiplying specialisations?

Scrum organization says “we are the team” and within that team, we are cross-functional, so we have a designer, back/front developer, and other roles demanded to deliver end-to-end functional scope. People still have a specialization or main competency, but in Scrum there is a permission to step out of your specialty to help others, as well as common goal, demonstration and mutual learning.

 

Sources

Henrik’s Blog

Article “Agile is about taming complexity”

Visual support produced by Nicolas Kalmanowitz, Agile Coach at OCTO Technology:

Articles suggested :

  1. BOOSTEZ vos compétences chez OCTO Academy
  2. Vivez l’expĂ©rience formation avec OCTO
  3. Les grands groupes devraient-ils s’inspirer des startups ?

Catégories: Blog Société

Les chaĂźnes de caractĂšres en Ruby

L'actualité de Synbioz - mar, 07/25/2017 - 23:00

Parce qu’il est bon de se rafraichir la mĂ©moire de temps en temps, aujourd’hui nous allons nous intĂ©resser aux diffĂ©rentes possibilitĂ©s que nous offre Ruby pour le formatage des chaĂźnes de caractĂšres.

Les chaßnes de caractÚres servent à représenter des clés (dans une structure JSON par exemple) ou bien afficher du texte. Pour manipuler ces morceaux de texte, Ruby nous offre une pléthore de méthodes que je vous propose de voir/revoir dans ce billet.

Lire la suite...

Catégories: Blog Société

Passer du mode projet au mode produit

Le why ?

“Le Time To Market est trop long”, “Nous n’avons aucune idĂ©e du bĂ©nĂ©fice apportĂ© par ce projet”, “On commence plein de choses et on ne termine rien”…

VoilĂ  des phrases que nous entendons tous les jours et qui font dire Ă  toutes les entreprises impliquĂ©es dans la rĂ©volution digitale qu’il faut remettre en cause le paradigme projet.

L’enjeu de ces entreprises n’est plus le respect du fameux triangle pĂ©rimĂštre-coĂ»t-dĂ©lai mais bien d’optimiser l’impact business Ă  long terme.

Que devient la traditionnelle date de fin de projet lorsque l’équipe commence Ă  mettre en service rapidement de premiĂšres versions du produit qui seront complĂ©tĂ©es par les retours frĂ©quents des utilisateurs ?

Nous devons alors changer de lunettes, passer du paradigme projet au paradigme produit pour s’assurer d’avoir le maximum d’impact sur le long terme, promouvoir une innovation efficace tout en “dĂ©-silotant” l’entreprise.

 En théorie

Ce changement de paradigme couvre 4 grands domaines :

  • Le pilotage par la valeur plutĂŽt qu’une approche budgĂ©taire
  • Des feedbacks clients nombreux et anticipĂ©s plutĂŽt qu’en fin de projet
  • Des dĂ©cisions rapides et frĂ©quentes plutĂŽt que lentes et anticipĂ©es
  • Une planification itĂ©rative plutĂŽt qu’une planification complĂšte

Du point de vue d’un gestionnaire de projet, cela revient à :

  • Limiter les risques liĂ©s aux engagements de dĂ©lai par des livraisons frĂ©quentes
  • MaĂźtriser la notion de coĂ»t par une Ă©quipe stable et dĂ©diĂ©e Ă  un sujet produit
  • Anticiper les bĂ©nĂ©fices par la production de valeur pour les clients
  • Utiliser le pĂ©rimĂštre comme seule variable d’ajustement
 En pratique

Cela commence toujours par la mise en place d’une Ă©quipe Agile de 5 Ă  8 personnes, pluri-disciplinaire, durable et dĂ©diĂ©e Ă  un produit.

L’équipe met rapidement en place des moyens pour obtenir du feedback des utilisateurs : data, analytics, tests utilisateurs, immersions, observations


Afin de gĂ©rer efficacement le build et le run, l’équipe va rapidement dĂ©velopper une stratĂ©gie sur la qualitĂ© logicielle afin de limiter l’impact des bugs : pyramide des tests en place, crĂ©ation de dette technique sous contrĂŽle, tests automatisĂ©s et bugs priorisĂ©s.

La budgĂ©tisation d’une telle Ă©quipe devient glissante (en gĂ©nĂ©ral sur 3 mois) afin de frĂ©quemment se poser la question du “arrĂȘter / continuer” en fonction du retour sur investissement espĂ©rĂ©.

De fait, la roadmap devient dynamique tout comme la stratégie produit qui se base avant tout sur des hypothÚses plutÎt que des opinions.

La clĂ© de voĂ»te du mode produit est le Product Owner de l’équipe qui doit ĂȘtre capable de dĂ©cisions rapides sur le produit mais aussi d’une bonne capacitĂ© Ă  communiquer et challenger (avec l’aide de spĂ©cialistes de l’expĂ©rience utilisateurs) les besoins des clients et des parties prenantes de l’entreprise.

 La FAQ “Comment rĂ©cupĂ©rer du feedback client ?”

Une session de tests utilisateurs (source : usability.de)

  • Par des contacts directs qualitatifs : observations et entretiens directs avec des utilisateurs
  • Des sondages quantitatifs : enquĂȘtes satisfaction (de type Net Promoter Score), sondage de positionnement, benchmark concurrentiel
  • Les mĂ©triques quantitatives d’usage issues d’outil d’analytics, de logs internes ou de requĂȘtes en base
    Les demandes client consultables dans les outils de ticketing
  • Des retours indirects par des experts internes : les commerciaux, le marketing, mais aussi le support ou le service formation
  • Des tests utilisateurs
  • Inviter des utilisateurs en dĂ©monstration
  • Organiser des ateliers de co-design avec des clients
  • CrĂ©er un comitĂ© / club utilisateur
“Comment faire quand nous n’avons pas accùs aux clients / utilisateurs ?”

Avoir des contacts directs avec les utilisateurs est souvent difficile Ă  obtenir par des Ă©quipes IT, bloquĂ©es par le marketing, les commerciaux ou les partenaires. Dans ce cas, vous pouvez utiliser un cheval de troie : partir d’une demande client urgente oĂč il sera lĂ©gitime de rencontrer le client directement, puis en profiter pour Ă©tendre la discussion sur d’autres sujets qui vous intĂ©ressent et demander au client de nouveaux contacts d’utilisateurs.

“Je dois refaire un produit qui existe dĂ©jĂ  (comme celui d’un concurrent par exemple), je sais donc ce que je veux et j’ai peur que l’approche produit soit une perte de temps !”

Le meilleur contre-exemple est Google Music, une application qui aurait pu ĂȘtre un simple copier / coller de Deezer ou Spotify et qui a rĂ©ussi progressivement Ă  devenir un rĂ©fĂ©rent dans la recommandation musicale tout en nĂ©gligeant certaines fonctionnalitĂ©s de ses concurrents.
Donc oui, l’approche produit est une perte de temps si vous souhaitez simplement vous mettre Ă  niveau de la concurrence – mais cette situation est gĂ©nĂ©ralement le signe d’un retard difficile Ă  rattraper, ce que l’approche produit pourrait transformer en opportunitĂ© !

“Comment tenir une roadmap quand on est monopolisĂ© par les demandes urgentes des clients ?”

Être pilotĂ© par les retours utilisateurs ne veut pas dire ĂȘtre pilotĂ© par les utilisateurs !

Exemple : Pour une solution de partage de fichiers en cours de refonte, des clients importants demandaient Ă  converser Ă  tout prix une gestion de profil iso-fonctionnelle de la version prĂ©cĂ©dente. AprĂšs des entretiens sur les besoins, le Product Owner a proposĂ© une refonte de la gestion de profil plus simple pour les utilisateurs … et les dĂ©veloppeurs.

Les remarques des clients ne sont que inputs. Il faut remonter aux besoins profonds du client au-delĂ  de la solution qu’il pousse spontanĂ©ment,, par exemple avec la mĂ©thode des “5 pourquois”. Il reste ensuite Ă©valuer leur pertinence par rapport Ă  votre vision produit. Vous pourrez alors vous focaliser sur l’important sans ĂȘtre esclave de l’urgent.

un exemple d’analyse de 5 pourquoi :

“A cause de notre image de marque, nous ne pouvons pas sortir un produit incomplet, comment faire ?”

C’est effectivement un grand changement d’état d’esprit et dont l’impact est beaucoup plus interne Ă  l’entreprise qu’externe. La plupart des clients d’aujourd’hui sont habituĂ©s Ă  des produits incomplets et c’est une tendance qui va se renforcer de plus en plus.
Le problĂšme vient souvent des objectifs donnĂ©s aux salariĂ©s, plus frĂ©quemment associĂ©s Ă  de la rĂ©alisation de solutions abouties qu’à de la valeur crĂ©Ă©e pour les utilisateurs.

En cas de refonte d’une solution existante, la facilitĂ© est effectivement de reproduire le pĂ©rimĂštre fonctionnel Ă  l’identique sans se poser de questions mais ce serait passer Ă  cĂŽtĂ© de l’opportunitĂ© de faire moins, plus vite et de meilleur qualitĂ© en supprimant tout le pĂ©rimĂštre qui n’apporte pas de valeur (rĂšgle des 80/20).

“Certaines ressources (UX, QA, devops, 
”) n’ont pas besoin d’ĂȘtre Ă  temps plein dans les Ă©quipes ? Comment optimiser les ressources ?”
  1. Vous avez besoin du “slack” : de la marge pour gĂ©rer les alĂ©as, l’amĂ©lioration continue et les innovations
  2. Les ressources sont en fait des humains 
 avec un cerveau souvent bien cùblé. Chacun a une expertise, mais peu aider ses coéquipiers : un expert UX ou des développeurs peut aider à rédiger les User Stories ou les tests.
  3. Optimiser les ressources n’a pas de sens en AgilitĂ©, c’est bien souvent contre productif car cela met le systĂšme complet en tension et le moindre imprĂ©vu fait dĂ©railler la machine; c’est la souplesse du systĂšme qui permet d’absorber efficacement et au plus tĂŽt les problĂšmes.
“Est-ce que le mode projet doit ĂȘtre interdit ?”

Non : le mode projet peut rester pertinent, notamment quand l’environnement est prĂ©dictible : il n’y a pas de dĂ©bat sur le problĂšme, le bĂ©nĂ©fice et la solution.

Le mode projet peut ĂȘtre rĂ©alisĂ© :

  • par des Ă©quipes projets temporaires en mode agile voire waterfall (si le plan de dĂ©veloppement est prĂ©dictible)
  • par des Ă©quipes produit : par exemple la rĂ©alisation d’une feature / epic sur plusieurs sprints
  • un projet transverse Ă  plusieurs Ă©quipes produit : par exemple le lancement Ă  l’international pour un site de e-commerce organisĂ© en 10 feature teams parallĂšles.
“Je suis Chef de Projet, qu’est-ce que je deviens ? ”

Comme vu dans le point précédent, il continuera à y avoir des projets, donc des besoins de chefs de projet.
Cependant, il y en aura sĂ»rement moins. Un repositionnement d’une grande partie des chefs de projets est nĂ©cessaire, souvent dans l’un de ces 3 rĂŽles selon le profil de la personne :

  • Chef de Produit/ Product Owner, pour ceux qui sont issus du mĂ©tier ou une bonne connaissance du marchĂ©
  • Tech leader, pour ceux qui ont une expertise technique et aiment aider l’équipe Ă  monter en compĂ©tence
  • Scrum-master, coach agile ou facilitateur, pour ceux qui ont une appĂ©tence pour l’amĂ©lioration du relationnel et des process
 Attention

Passer en mode produit n’est pas qu’une simple rĂ©organisation de l’IT ou R&D, c’est un changement de culture qui implique toute l’entreprise (direction, RH, marketing, commerce, finances, mĂ©tier
).

MĂȘme si nous recommandons de commencer progressivement par des expĂ©rimentations pilotes, il s’agit Ă  terme d’une transformation d’entreprise qui exige dĂšs le dĂ©part un sponsorship fort au niveau de la Direction GĂ©nĂ©rale.

 Recettes de Coach / Astuces

“Je passe beaucoup de temps avec le Product Owner pour lui expliquer l’importance de la communication avec les parties prenantes car souvent les entreprises ont peur de ce nouveau rĂŽle qu’ils imaginent ĂȘtre un chef produit omnipotent. Mon truc, c’est de faire venir ces parties prenantes dans l’équipe pour qu’ils constatent de visu que celui qui dĂ©cide dans une Ă©quipe produit, c’est l’utilisateur avant tout !” (Basile)

“J’aime demander aux dirigeants de raconter des gros Ă©checs projets ; il y en a toujours et ils ont traumatisĂ© l’entreprise ! Je m’appuie sur ces “blessures” et leur cri du coeur “plus jamais ça !” pour les inciter Ă  expĂ©rimenter une autre façon de faire.” (Dominique)

“Une Ă©quipe produit doit ĂȘtre capable de mettre en production par elle-mĂȘme, sans contraintes externes, rapidement et frĂ©quemment. Pour cela, je consacre toujours les premiers jours (ou semaines) de l’équipe produit Ă  valider cette capacitĂ© en faisant l’exercice de dĂ©ploiement complet d’une pseudo-fonctionnalitĂ© (par exemple une page “Hello World”). Rien de pire qu’une Ă©quipe produit incapable de dĂ©ployer son code, elle perd tout son sens” (Basile)

 Je ne sais pas / j’aimerais essayer Product Owner ou Product Manager, telle est la question ?

VoilĂ  une question Ă  la fois simple et compliquĂ©e. D’un cĂŽtĂ© on aimerait dire que c’est la mĂȘme chose et qu’il n’y a pas de diffĂ©rence et de l’autre on constate que le premier est tournĂ© vers l’équipe et le delivery et que l’autre est tournĂ© vers les utilisateurs et la stratĂ©gie
 mais quelle est la bonne rĂ©ponse ? On ne sait pas encore !

Comment contester les idées des managers ou dirigeants ?

Il s’agit du principal frein culturel que nous ayons rencontrĂ© dans la diffusion du mode produit. Alors que la mĂ©thode prĂ©suppose la possibilitĂ© d’invalider les idĂ©es par des petites expĂ©rimentations, la culture hiĂ©rarchique empĂȘche les Product Owners / Product Managers de challenger une fausse bonne idĂ©e d’un dirigeant parfois intimidant.

Voici nos pistes de solutions :

  • de la sensibilisation en amont des dirigeants sur le mode produit
  • demander aux dirigeants de se remĂ©morer des histoires de prĂ©cĂ©dents Ă©checs de grands projets ayant eu peu d’impact
  • s’appuyer sur les donnĂ©es avant de s’engager
  • utiliser des canevas pour s’obliger Ă  remonter au besoin avant la solution (par ex. le lean canvas)
Au-delĂ  du produit, l’expĂ©rience client

Dans la perception des utilisateurs, l’expĂ©rience produit dĂ©passe largement le cadre de la simple application informatique. Elle inclut l’expĂ©rience utilisateur avec le marketing, le commerce, la livraison, le support, …Nous nous demandons encore comment inclure ces compĂ©tences. Comment les impliquer vraiment dans le dĂ©veloppement alors qu’ils sont monopolisĂ©s sur de multiples sujets ? Voire, peut-on les inclure comme membres dĂ©diĂ©s dans les Ă©quipes pluridisciplinaires? Ceci implique de dĂ©composer l’entreprise en mini-PME autour d’offres d’expĂ©rience client…

 Témoignages de nos clients

“Donner des objectifs dans le cadre d’entretiens annuels Ă  quelqu’un qui travaille dans une Ă©quipe produit n’a pas de sens, il faut le voir plus frĂ©quemment et lui donner des objectifs non plus en lien avec le pĂ©rimĂštre Ă  rĂ©aliser mais avec la valeur Ă  produire, c’est un nouveau challenge !” (Manager DSI Commerce)

“Je comprends que je ne dois plus demander des solutions Ă  l’équipe sans contexte, mais exprimer mes besoins sous forme de questions et d’hypothĂšses afin de les laisser me proposer la meilleure solution.” (Responsable Marketing)

“Pour la premiĂšre fois depuis que je travaille ici, je comprends ce que je fais pour le client” (DĂ©veloppeur Ă©quipe produit)

“Je trouve que la communication est meilleure, et que les gens se sentent plus impliquĂ©s.” (DĂ©veloppeur – Ă©quipe produit pilote)

“Je me rends compte que les livraisons frĂ©quentes ont grandement amĂ©liorĂ© la confiance des clients en l’équipe et ce malgrĂ© l’absence d’engagement sur un pĂ©rimĂštre prĂ©cis.” (Responsable mĂ©tier)

 Pour en savoir plus

Le framework Cynefin (Complexité) 
Le petit-déjeuner OCTO passer du mode Projet au mode Produit
DĂ©velopper la culture produit
Mon processus de design en tant que Product Owner sans UX designer
La feature team au-delĂ  du buzzword

Catégories: Blog Société

Partagez la connaissance

Partagez BlogsdeDeveloppeurs.com sur les réseaux sociaux