Developpez.com

Le Club des Développeurs et IT Pro

Pourquoi Google a-t-il opté pour l'emploi d'un seul code base comme modèle de gestion de sources ?

Un de ses ingénieurs explique

Le 2015-09-16 12:04:26, par Stéphane le calme, Chroniqueur Actualités
Rachel Potvin, Engineering Manager Google, a expliqué la raison pour laquelle Google utilise un seul code base. « De prime abord, certains d’entre vous se disent probablement que c’est insensé » reconnait-elle.

Pour faire valoir les bénéfices d’une telle stratégie, elle a évoqué sa propre expérience : « j’ai débuté ma carrière dans l’industrie du jeu vidéo où j’ai travaillé comme développeur logiciel pendant plusieurs années. Et, à cette période, l’entreprise pour laquelle je travaillais avait l’habitude de bosser sur plusieurs jeux vidéo au même moment et chaque jeu était sur son propre dépôt. Il arrivait souvent que ces jeux soient conçus à partir des mêmes moteurs. Aussi, nous avions une copie du code du moteur d’un jeu dans chacun de nos dépôts ». Si ces jeux allaient évoluer de manière indépendante, certains managers ont décidé que dans le cas où une fonctionnalité devait être implémentée dans un code base devait également être portée dans les autres. Elle a qualifié ce processus de difficile.

Bien des fois chez Google, la question de savoir s’il fallait diviser ce code base géant en plusieurs code base s’est posée, mais à chaque fois l’entreprise a décidé de garder un seul code base et d’investir dans l’évolutivité. Pourquoi ? Elle a présenté les avantages et les inconvénients.

Avant d’entrer dans le vif du sujet, Google a d’abord présenté les statistiques de son dépôt : 1 milliard de fichiers, 9 millions de fichiers source, 2 milliards de ligne de code, un historique de 35 millions de modifications (45 000 par jour en moyenne – 15 000 effectués par des humains, 30 000 par des systèmes automatisés) pour un poids total de 86 Téraoctets.



L’entreprise a également présenté son workflow. Le code est d’abord examiné avant d’être porté dans le dépôt (par des humains ou des outils automatisés). Chaque fichier a un ensemble de propriétaires qui doivent approuver les changements effectués dans leur zone sur le dépôt. Des tests et des vérifications automatisées sont effectués avant et après le portage. Une restauration automatique d’une modification pourrait arriver en cas de plantage généralisé. Parmi les outils à la disposition des Googlers figurent Critique (pour examiner le code), Tricorder (pour des analyses statiques de la surface du code dans Critique) ou encore TAP (une infrastructure de tests complets avant et après les portages).




Après avoir donné tous ces éléments, Google cite quelques avantages, notamment :

  • Un versioning unifié ;
  • Un partage et une réutilisation extensifs du code ;
  • Une gestion simplifiée de la dépendance ;
  • Des changements au niveau atomique ;
  • Un refactoring à grande échelle et une modernisation du code base ;
  • Une collaboration entre les équipes ;
  • Des limites d’équipe et une possession du code flexibles ;
  • Une visibilité du code et une arborescence claire qui fournissent un espace de noms implicite d’équipe.



Les inconvénients, quant à eux, sont essentiellement relatifs aux coûts associés à ce modèle mais également à la complexité du code base





En conclusion, Google estime que ce modèle de gestion de source marche bien lorsqu’il est accompagné d’une culture d’ingénierie de transparence et de collaboration. Si Google a beaucoup investi sur les outils d’évolutivité et de productivité afin de soutenir ce modèle à cause des avantages significatifs qu’il en retire, l’entreprise reconnaît que cette approche pourrait ou pas être la meilleure approche pour votre entreprise. Rachel Potvin et un de ses collègues ont écrit un article à ce sujet qui va plus en profondeur et qui sera publié « plus tard au courant de cette année ».


Source : YouTube

Et vous ?

Qu'en pensez-vous ?
  Discussion forum
7 commentaires
  • Bousk
    Rédacteur/Modérateur
    Tel que je le comprends, ils ont un seul et unique repo pour tous leurs projets ?!
    Parce qu'autant, oui dupliquer le moteur pour chaque projet, c'est la misère pour la maintenance (chacun (re)fait les fix de son côté), mais on a inventé les sous-repo/external depuis, en tous cas sur SVN, Git et Mercurial !
  • DonQuiche
    Expert confirmé
    Envoyé par air-dex
    Quoique. Est-ce que les numéros de commits veulent encore dire quelque chose à l'ère des DCVS comme git ?
    Non, justement.

    Ceci n'est pas un avantage.
    "Partager et réutiliser" ne veut pas dire "créer des dépendances inutiles". Cela veut simplement dire que si quelqu'un a besoin d'un code pour une tâche précise, il peut aisément chercher dans toute la base de Google et recopier un code dont il sait qu'il est de qualité, testé et sans problèmes de licences. C'est une bonne pratique.

    Comme si c'était les outils de gestion de dépendances qui manquaient de nos jours...
    Et il est toujours mieux de ne pas avoir besoin d'outils supplémentaire, de ne pas perdre de temps avec, de ne pas avoir besoin de former des employés à cela.

    En Java il y a une convention sur les noms de packages qui consiste à faire commencer ses noms de packages par son site internet à l'envers (exemple : packages com.google.* pour tous les packages Java de Google). Mettre des conventions d'espaces de noms pour tous les projets de la boîte suffit donc à reproduire cela et pas besoin d'une code de base unifiée pour cela. Ne me dites pas que Google n'est pas suffisamment structuré pour mettre en place une telle pratique.
    Si tu veux modifier le projet XYZ, il te suffit d'ouvrir le repo et de chercher le dossier racine "XYZ". C'est quand même plus sympa que de faire un "ls" pour voir une liste de dossiers ayant les noms d'équipes dont tu ne sais pas qui elles sont et ce qu'elles font. Avec leur système pas besoin de savoir qui est propriétaire de "XYZ", ce qui permet aussi de pouvoir distribuer ou transférer la propriété d'un projet.

    Au lieu d'avoir une liste de repos ayant les noms d'équipes dont tu ne sais pas qui elles sont et ce qu'elles font, tu as une liste de projets.

    Si une équipe n'a accès qu'à une partie de la base de code, alors c'est pareil que d'avoir un repo pour chaque projet.
    Tu as mal compris ce qu'ils veulent dire :
    a) Tout le monde peut intervenir sur tout (si tu découvres un bug dans X tu peux directement soumettre une pull request plutôt qu'un rapport de bug)
    b) Certains projets n'ont pas (plus) d'équipe dédiée mais sont utilisés et modifiés par plusieurs équipes. Et une équipe peut temporairement s'approprier le contrôle d'un projet commun.

    Le second point est un modèle intéressant pour certaines infrastructures communes à la boîte, même si je présume qu'ils conservent un ou des référents qui font autorité.
  • Logan Mauzaize
    Rédacteur/Modérateur
    Envoyé par Stéphane le calme
    Pour faire valoir les bénéfices d’une telle stratégie, elle a évoqué sa propre expérience : « j’ai débuté ma carrière dans l’industrie du jeu vidéo où j’ai travaillé comme développeur logiciel pendant plusieurs années. Et, à cette période, l’entreprise pour laquelle je travaillais avait l’habitude de bosser sur plusieurs jeux vidéo au même moment et chaque jeu était sur son propre dépôt. Il arrivait souvent que ces jeux soient conçus à partir des mêmes moteurs. Aussi, nous avions une copie du code du moteur d’un jeu dans chacun de nos dépôts ». Si ces jeux allaient évoluer de manière indépendante, certains managers ont décidé que dans le cas où une fonctionnalité devait être implémentée dans un code base devait également être portée dans les autres. Elle a qualifié ce processus de difficile.
    Je pensais pas que le "feature branching" et le "release branching" était si peu connu. Surtout de la part de quelqu'un travaillant chez Google ...

    Envoyé par Stéphane le calme
    Qu'en pensez-vous ?
    Je pense qu'on manque de beaucoup d'informations. Parce que décrit comme cela, ce n'est pas viable :
    • Envoyé par Stéphane le calme
      un historique de 35 millions de modifications (45 000 par jour en moyenne – 15 000 effectués par des humains, 30 000 par des systèmes automatisés)
      Les gens passent leur temps à faire des merges ???
    • Envoyé par Stéphane le calme
      Un versioning unifié
      Si je fais une nouvelle release d'un projet, je suis obligé de prendre la dernière version de mes dépendantes ???
    • Envoyé par Stéphane le calme
      Un partage et une réutilisation extensifs du code
      Quelle différence avec une gestion de configuration des binaires ??? Ou une indexation des sources ???
    • Envoyé par Stéphane le calme
      Une gestion simplifiée de la dépendance
      Idem ??? Ou est la simplicité si tout impact d'une dépendance impactent mon projet ???
    • Envoyé par Stéphane le calme
      Des changements au niveau atomique
      Je vois pas trop l'avantage ??? Toute modification doit être gérée globalement ou pas du tout ???
    • Envoyé par Stéphane le calme
      Une collaboration entre les équipes
      D'expérience moins les groupes dépendent les uns des autres, mieux c'est ???
    • Envoyé par Stéphane le calme
      Une visibilité du code et une arborescence claire qui fournissent un espace de noms implicite d’équipe.
      Parce que rechercher dans "1 milliard de fichiers, 9 millions de fichiers source, 2 milliards de ligne de code, un historique de 35 millions de modifications [...] pour un poids total de 86 Téraoctets", il ne faut pas indexer ??? Parce qu'une unique arborescence c'est le seul moyen d'organiser et le plus efficace (cf. catégorisation, mot clé, etc.) ???


    Envoyé par Stéphane le calme
    En conclusion, Google estime que ce modèle de gestion de source marche bien lorsqu’il est accompagné d’une culture d’ingénierie de transparence et de collaboration. Si Google a beaucoup investi sur les outils d’évolutivité et de productivité afin de soutenir ce modèle à cause des avantages significatifs qu’il en retire, l’entreprise reconnaît que cette approche pourrait ou pas être la meilleure approche pour votre entreprise.
    Je pense que s'ils avaient adopté une autre approche avec le même investissement dans les outils. Le résultat aurait été similaire. Il serait intéressant qu'il compare leur modèle avec d'autres en supposant la même qualité d'outillage ...

    Envoyé par Stéphane le calme
    L’entreprise a également présenté son workflow. Le code est d’abord examiné avant d’être porté dans le dépôt (par des humains ou des outils automatisés). Chaque fichier a un ensemble de propriétaires qui doivent approuver les changements effectués dans leur zone sur le dépôt. Des tests et des vérifications automatisées sont effectués avant et après le portage. Une restauration automatique d’une modification pourrait arriver en cas de plantage généralisé.
    Ce que je crois en comprendre c'est qu'il existe une méga-branche principale mais que chaque "groupe de projet" dispose d'une branche qui est un assemblage/vue de différents répertoires "tiers" aux versions souhaitées. Un peu comme on le peut le faire avec les "external" réflexifs de SVN ou les VOBs de ClearCase. On peut également avoir le même fonctionnement avec CVS mais cela demande une certaine organisation. On pourrait également atteindre le même objectif avec Git mais il n'est pas possible de référencer un groupe de fichiers (ie répertoire) par un hash comme on le fait avec un commit (à ma connaissance).

    En résumé, ils font la gestion de configuration au niveau du source et non du binaire. Je vois qu'un intérêt moyen (mais non nul) surtout devant une telle quantité.

    Envoyé par DonQuiche
    "Partager et réutiliser" ne veut pas dire "créer des dépendances inutiles". Cela veut simplement dire que si quelqu'un a besoin d'un code pour une tâche précise, il peut aisément chercher dans toute la base de Google et recopier un code dont il sait qu'il est de qualité, testé et sans problèmes de licences. C'est une bonne pratique.
    Si c'est pour recopier, pas besoin d'un gros dépôt de source. Juste d'une bonne indexation.

    Envoyé par DonQuiche
    Et il est toujours mieux de ne pas avoir besoin d'outils supplémentaire, de ne pas perdre de temps avec, de ne pas avoir besoin de former des employés à cela.
    Leurs outils sont des outils supplémentaires auxquels il faut former les employés. Qui de plus venant d'autres horizons devront désapprendre les standards que sont Maven/Ivy, Setuptools/Pip, etc.

    Envoyé par DonQuiche
    Si tu veux modifier le projet XYZ, il te suffit d'ouvrir le repo et de chercher le dossier racine "XYZ". C'est quand même plus sympa que de faire un "ls" pour voir une liste de dossiers ayant les noms d'équipes dont tu ne sais pas qui elles sont et ce qu'elles font. Avec leur système pas besoin de savoir qui est propriétaire de "XYZ", ce qui permet aussi de pouvoir distribuer ou transférer la propriété d'un projet.
    Tu fais un "ls" sur "1 milliard de fichiers pour un poids total de 86 Téraoctets" ?

    Envoyé par DonQuiche
    Au lieu d'avoir une liste de repos ayant les noms d'équipes dont tu ne sais pas qui elles sont et ce qu'elles font, tu as une liste de projets.
    Je connais pas d'organisation qui nomme ces dépôts avec le nom des équipes.

    Envoyé par DonQuiche
    Tu as mal compris ce qu'ils veulent dire :
    a) Tout le monde peut intervenir sur tout (si tu découvres un bug dans X tu peux directement soumettre une pull request plutôt qu'un rapport de bug)
    b) Certains projets n'ont pas (plus) d'équipe dédiée mais sont utilisés et modifiés par plusieurs équipes. Et une équipe peut temporairement s'approprier le contrôle d'un projet commun.
    Le second point est un modèle intéressant pour certaines infrastructures communes à la boîte, même si je présume qu'ils conservent un ou des référents qui font autorité.
    C'est quoi la différence avec N dépôts ?

    Envoyé par DonQuiche
    Je ne vois pas en quoi c'est un problème. C'est un maigre sacrifice nécessaire, aisément remplacé par des numéros de build serveur, des dates de build ou des versons publiques.
    Cela signifie que tu colles la même étiquette pour tous tes projets. A moins de tous les livrer en même temps, cela n'a pas pas beaucoup de sens.

    Envoyé par DonQuiche
    Sauf que certains projets sont intimement liés (micro-services par ex) et que pour cette raison une même équipe utilise un repo commun plutôt qu'un repo par projet. Dans ce cas-là les repos portent le nom de l'équipe. Ou le nom d'un super-projet. Dans tous les cas cela complique la visibilité pour une personne extérieure.
    Le principe des micro-services c'est justement de rendre de l'indépendance à des composants. Rien n'empêche d'être intelligent et de créer des dépôts séparés mais avec un préfixe si c'est le besoin. Ne compare pas une organisation sainement choisi avec une autre complètement inappropriée. De toutes façons chercher dans 86 dépôts de 1To chacun ou dans 1 dépot de 86To, tu pourras jamais tout faire tenir sur ton poste de travail.

    Envoyé par DonQuiche
    Si tu interviens sur X qui dépend de Y et que tu découvres un bug dans Y, autant soumettre directement une résolution.
    A condition d'en avoir l'autorité, dans ce cas des dépôts multiples qui plus est avec des "external" rendent le même service.

    Envoyé par DonQuiche
    La nature humaine étant ce qu'elle est les individus partagent, contribuent et consomment davantage s'ils n'ont aucune configuration ou recherche à faire parce que tout est dans le même repo et qu'ils peuvent tout faire sans bouger de leur IDE. Dans le cas de Google c'est simple comme parcourir ton repo : contribuer à un autre projet est aussi simple que de contribuer à ton projet.
    Sauf qu'il est peut probable que tu es "1 milliard de fichiers pour un poids total de 86 Téraoctets" sur ton disque ...
  • air-dex
    Membre expert
    Envoyé par DonQuiche
    Non, justement.
    Et c'est bien ça le problème.

    Envoyé par DonQuiche
    Si tu veux modifier le projet XYZ, il te suffit d'ouvrir le repo et de chercher le dossier racine "XYZ". C'est quand même plus sympa que de faire un "ls" pour voir une liste de dossiers ayant les noms d'équipes dont tu ne sais pas qui elles sont et ce qu'elles font. Avec leur système pas besoin de savoir qui est propriétaire de "XYZ", ce qui permet aussi de pouvoir distribuer ou transférer la propriété d'un projet.
    Mais on se fiche de qui est propriétaire de tel ou tel projet. D'où la convention de nommage. Ton projet XYZ sera dans le repo XYZ et il te suffit juste d'ouvrir directement ton repo XYZ dans la liste des repo au lieu d'aller te perdre dans une arborescence.

    Envoyé par DonQuiche
    Tu as mal compris ce qu'ils veulent dire :
    a) Tout le monde peut intervenir sur tout (si tu découvres un bug dans X tu peux directement soumettre une pull request plutôt qu'un rapport de bug)
    b) Certains projets n'ont pas (plus) d'équipe dédiée mais sont utilisés et modifiés par plusieurs équipes. Et une équipe peut temporairement s'approprier le contrôle d'un projet commun.

    Le second point est un modèle intéressant pour certaines infrastructures communes à la boîte, même si je présume qu'ils conservent un ou des référents qui font autorité.
    Mais dans tous les cas les projets sont distincts. Si tu interviens sur X tu interviens sur X, pas sur X, Y, Z et T qui sont tous dans le même repo.
  • germinolegrand
    Membre expert
    Intéressant, pour avoir galéré avec plusieurs dizaines de dépôts avec des dépendances pas simples, je dois que reconnaître que cette approche n'est pas absurde du tout.

    Bon, l'inconvénient c'est que c'est bien pour une codebase où il n'y a pas de code figé, or c'est souvent le cas lorsque l'on ne souhaite plus maintenir un projet, mais l'utiliser tout de même...
  • air-dex
    Membre expert
    Envoyé par Stéphane le calme
    Pour faire valoir les bénéfices d’une telle stratégie, elle a évoqué sa propre expérience : « j’ai débuté ma carrière dans l’industrie du jeu vidéo où j’ai travaillé comme développeur logiciel pendant plusieurs années. Et, à cette période, l’entreprise pour laquelle je travaillais avait l’habitude de bosser sur plusieurs jeux vidéo au même moment et chaque jeu était sur son propre dépôt. Il arrivait souvent que ces jeux soient conçus à partir des mêmes moteurs. Aussi, nous avions une copie du code du moteur d’un jeu dans chacun de nos dépôts ». Si ces jeux allaient évoluer de manière indépendante, certains managers ont décidé que dans le cas où une fonctionnalité devait être implémentée dans un code base devait également être portée dans les autres. Elle a qualifié ce processus de difficile.
    Quand un composant est utilisé sur plusieurs projets, n'est-il pas préférable que celui-ci existe en tant que projet à part et ait donc son propre repo à ce titre là ? En plus comme le dit Bousk nous (D)CVS ont de quoi gérer des sous-projets dans le projet principal. Bref cette idée de base de code unifiée part d'une mauvaise pratique, donc ça pue d'entrée.

    Quant aux avantages ils sont souvent fumeux AMHA :

    Envoyé par Stéphane le calme
    • Un versioning unifié
    On a donc le versionnage de tous les projets Google qui s'entremêmelent. La version n+1 d'un projet de chez Google n'est donc pas forcément la version n+1 du projet en question. Pas très cohérent ça.

    Quoique. Est-ce que les numéros de commits veulent encore dire quelque chose à l'ère des DCVS comme git ?

    Envoyé par Stéphane le calme
    • Un partage et une réutilisation extensifs du code
    Ceci n'est pas un avantage.

    Envoyé par Stéphane le calme
    • Une gestion simplifiée de la dépendance
    Comme si c'était les outils de gestion de dépendances qui manquaient de nos jours...

    Envoyé par Stéphane le calme
    • Des limites d’équipe et une possession du code flexibles
    Si une équipe n'a accès qu'à une partie de la base de code, alors c'est pareil que d'avoir un repo pour chaque projet.

    Envoyé par Stéphane le calme
    • Une visibilité du code et une arborescence claire qui fournissent un espace de noms implicite d’équipe.
    En Java il y a une convention sur les noms de packages qui consiste à faire commencer ses noms de packages par son site internet à l'envers (exemple : packages com.google.* pour tous les packages Java de Google). Mettre des conventions d'espaces de noms pour tous les projets de la boîte suffit donc à reproduire cela et pas besoin d'une code de base unifiée pour cela. Ne me dites pas que Google n'est pas suffisamment structuré pour mettre en place une telle pratique.
  • DonQuiche
    Expert confirmé
    Envoyé par air-dex
    Et c'est bien ça le problème.
    Je ne vois pas en quoi c'est un problème. C'est un maigre sacrifice nécessaire, aisément remplacé par des numéros de build serveur, des dates de build ou des versons publiques.

    D'où la convention de nommage. Ton projet XYZ sera dans le repo XYZ et il te suffit juste d'ouvrir directement ton repo XYZ dans la liste des repo au lieu d'aller te perdre dans une arborescence.
    Sauf que certains projets sont intimement liés (micro-services par ex) et que pour cette raison une même équipe utilise un repo commun plutôt qu'un repo par projet. Dans ce cas-là les repos portent le nom de l'équipe. Ou le nom d'un super-projet. Dans tous les cas cela complique la visibilité pour une personne extérieure.

    Et je ne vois pas pourquoi tu te perdrais dans une arborescence : à la racine du repo se trouvent tous les projets.

    Mais dans tous les cas les projets sont distincts. Si tu interviens sur X tu interviens sur X, pas sur X, Y, Z et T qui sont tous dans le même repo.
    Si tu interviens sur X qui dépend de Y et que tu découvres un bug dans Y, autant soumettre directement une résolution.

    La nature humaine étant ce qu'elle est les individus partagent, contribuent et consomment davantage s'ils n'ont aucune configuration ou recherche à faire parce que tout est dans le même repo et qu'ils peuvent tout faire sans bouger de leur IDE. Dans le cas de Google c'est simple comme parcourir ton repo : contribuer à un autre projet est aussi simple que de contribuer à ton projet.