Maison  >  Article  >  Java  >  L'erreur d'une ligne de mille dollars - SBT + PlayFramework

L'erreur d'une ligne de mille dollars - SBT + PlayFramework

PHPz
PHPzoriginal
2024-07-17 16:05:23329parcourir

The thousand dollars one line mistake - SBT + PlayFramework

Aujourd'hui, tout le monde parle de l'importance d'avoir une bonne expérience de développeur, car elle aura de nombreux effets secondaires positifs, tels que, mais sans s'y limiter :

  • Vitesse de développement / Productivité

  • Qualité du code / Maintenance

  • Économies de coûts, etc

Cependant, nous travaillons souvent sur des projets pour lesquels, à un moment donné dans le passé, un petit morceau de code a été ajouté pour rendre le projet plus rapide, ou même pour corriger quelque chose, peut-être que quelqu'un essayait de rendre la construction plus rapide, ou essayant même d'offrir aux ingénieurs une meilleure expérience de développement. C'était le cas dans cette histoire.

Il y a quelques années, dans un projet sur lequel nous avons travaillé (avant même que je fasse partie de l'entreprise), un problème de construction de SBT, Scala et du framework de jeu a été identifié, où le temps de compilation pour construire le projet localement prenait environ 3 à 5 minutes selon la machine. Une tentative de résolution du problème a été effectuée. La structure du projet a été divisée en 2 comme ci-dessous :
Avant

ProjectA
  /api
 /core
 /app

Après

ProjectA
 /core
 /app

ProjectApi
  /api

Ce qui suit a été ajouté au build.sbt

lazy val projectA = (project in file("."))
  .enablePlugins(...)
  .settings(commonSettings)
  .aggregate(api)
  .dependsOn(api)

lazy val api = project.settings(commonSettings)

Ce faisant, cela a amélioré le temps de compilation, uniquement pendant la construction sur le pipeline CI, je ne suis pas sûr que cela ait aidé pendant la phase de développement, cependant, cela a ajouté un nouveau et horrible bug qui a fait perdre des milliers aux développeurs d'heures de travail.

Après l'ajout de cette ligne, les développeurs ont commencé à remarquer combien de temps il fallait simplement pour exécuter un simple
sbt s'exécute localement, comme pour chaque changement dans la base de code désormais, une compilation complète était nécessaire.

Le voyage pour comprendre le problème

Selon documenté dans le manuel de référence SBT - Multiprojet

Il est important de noter les deux définitions de l'Agrégation et cela dépend de

L'agrégation signifie que l'exécution d'une tâche sur le projet agrégé l'exécutera également sur les projets agrégés

Un projet peut dépendre du code d'un autre projet. Cela se fait en ajoutant un appel de méthode dependOn. Par exemple, si le noyau avait besoin d'util sur son chemin de classe.

Après avoir passé un jour ou deux à lire des documents et de nombreuses tentatives frustrées pour résoudre le problème, j'ai fini par arriver à ce Github - Recompilation fallacieuse dans une version multi-projets. Ce n'était pas le correctif en lui-même, cependant, cela m'a éclairé à la fin. du tunnel pour comprendre que le problème venait bien de la configuration multi-projets.

Et de plus, j'ai compris ce qui se passait, et ainsi, mon fichier build.sbt était aussi simple que :

lazy val projectA = (project in file("."))
  .enablePlugins(...)
  .settings(commonSettings)
  .dependsOn(api)

lazy val api = (project in file("api"))
  .settings(commonSettings)

Il y a eu un problème avec la façon dont nous avons configuré le projet A dans SBT. Nous avons demandé à SBT d'inclure l'API du projet (ce qui était correct), mais la définition de l'API pointait vers la racine entière du projet. Cela signifiait que :

Chaque fois que l'API avait besoin d'être compilée, SBT essayait également de compiler le projet A lui-même.
Puisque projectA avait besoin de l'API pour se compiler, cela déclencherait une autre compilation d'API.
Cela a créé une boucle sans fin, obligeant les développeurs à supprimer SBT et à tout nettoyer et compiler manuellement pour chaque changement de code.
Voici ce qui s'est passé en termes plus simples :

Nous avons demandé à SBT d'inclure l'API du projet.
La définition de l'API faisait référence à l'ensemble du projet.
La compilation de l'API a déclenché une compilation complète du projet (y compris à nouveau l'API).
Cette boucle rendait SBT très lent et frustrant pour les développeurs.

L'équipe travaillait sur ce problème depuis au moins 4 ans...

Conséquences : résoudre le problème

Après avoir dit à mes coéquipiers que j'avais déjà fusionné une fonctionnalité surprise sur master, les gens ne comprenaient pas ce qui se passait, cependant, je voulais voir le bonheur sur leurs visages, j'ai dit à toute l'équipe d'impliquer master dans n'importe quel branche sur laquelle ils travaillaient, certains d'entre eux n'ont rien remarqué du premier coup, d'autres ont commencé à remarquer qu'après avoir modifié un code dans la base de code, il ne compilait que le fichier concerné en quelques secondes, et non en quelques minutes comme auparavant. Et la meilleure surprise a été lorsqu'un des coéquipiers l'a remarqué et a dit à voix haute dans le bureau.

Gust... avez-vous résolu le problème de la boucle de compilation ? Je travaille sur quelque chose ici et je reçois un retour instantané pour toute modification apportée au code.

À cette époque, j'ai dû l'admettre et partager la nouvelle avec tous les autres ingénieurs, cela a fait de moi un ingénieur plus heureux car maintenant je suis heureux de travailler sur ce projet et de ne pas attendre longtemps une compilation complète sur notre projet. .

Si vous sentez que quelque chose est à notre goût, à tout moment, quoi que vous fassiez, rappelez-vous que vous avez la possibilité de l'améliorer, n'oubliez jamais ce que vous avez commencé.

Si vous aimez lire cet article ou si vous souhaitez qu'il ait plus de contenu, faites-le-moi savoir dans les commentaires, je suis heureux de partager davantage sur ce voyage.

Merci d'avoir lu.

Quelques statistiques du projet :

Début du projet :

  • Environ 4 mille fichiers Java

  • Environ 300 modèles Twirl

  • Temps de compilation avant améliorations 3 à 5 minutes pour tout changement dans le code

  • Temps de compilation après améliorations en moyenne de 1 minute et 20 secondes pour une compilation complète

  • Temps de compilation après améliorations en moyenne de 5 à 10 secondes pour tout changement avec retour instantané (le plus de temps passé est Playframework qui redémarre le serveur HTTP)

Image de couverture réalisée par l'IA.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Littéraux en JavaArticle suivant:Littéraux en Java