Problème framework web scraping

a marqué ce sujet comme résolu.

Hello,

On a un énorme souci au niveau du framework de web scraping dans ma boîte actuelle.

Il fonctionne assez bien et permet d’automatiser et de créer un grand nombre de workflows assez facilement.

Le soucis, c’est principalement la maintenance et l’onboarding du framework :

  • On a un grand nombre de workflow qui tombe en panne chaque jour (ou qui ont des soucis mineurs), résultat : On doit obligatoirement réparer, soit c’est le site qui change ses sélecteurs ou ses routes ; Soit c’est le framework qui casse à un instant T

  • On n’a une multitude d’helpers en tous genres, de fonctions et aucun moyen de connaître leurs existences vu qu’y a 0 doc et pas d’autocompletion complète vu que JS

  • J’ai aucun moyen de savoir en plus quand je découvre une fonction, ce qu’elle prend ou renvoie comme paramètre par ce que 0 doc, des noms de variables pas toujours pertinent.

  • Le code du framework a été fais par une seule personne (qui apprenait node en même temps) ainsi le code est bancal, mauvaise utilisation des promises, des arrow function, 0 classe, des proto rédéfinis par dessus, et une mauvaise connaissance de la différence entre const et let

C’est assez difficile pour moi et j’aimerai établir une stratégie pour revenir à une situation stable sans avoir à tout péter vu qu’on a quand même un produit qui tourne.

Vous auriez des suggestions / des pistes ? Je n’ai pas encore assez d’xp sur le terrain pour avoir des suggestions vraiment pertinente

Salut,

Une stratégie qui marche pas mal pour réécrire/refactorer en profondeur un code source qui a mal vieilli est celle du figuier étrangleur. L’idée est principalement de réécrire les extrémités (en terme d’interdépendance avec les autres composants) de l’application avec des abstractions et du code propre. À chaque étape de progression ça nécessite d’écrire un peu de code voué à disparaitre pour faire le lien avec le code "legacy", mais l’avantage est que tu n’as qu’à réfléchir sur une toute petite portion du code à la fois dont le reste du code ne dépend pas trop (et au-fur-et-à-mesure que tu progresses, le code qui dépend du composant que tu es en train de réécrire est déjà propre, et donc facile à refactoriser un peu lors d’ajustement des abstractions).

C’est une stratégie qu’on utilise pour rendre un vieux code Fortran maintenable. C’est pas bien mieux que JS comme langage (peut être même pire) : standard imbitable (et franchement mal conçu), support lamentable par les compilos comme il n’y a pas de demande forte, pas de tooling, et écrire la moindre abstraction demande un boilerplate plus gros que le code métier. Au moins par rapport à JS on a du typage statique ce qui facilite le refactoring mais comme tu peux le voir c’est loin d’être idéal. On n’a aussi pas de développeur de métier (on est des scientifiques) mais on a un noyau de gens avec une culture du développement logiciel suffisante pour écrire un code de qualité raisonnable. Et franchement, cette méthode de s’attaquer aux bords pour progresser petit à petit est très efficace même si on est entre "amateurs" avec un langage bien pourri.

Donc si tu arrives à identifier des composants qui sont relativement indépendants du reste, je conseillerai fortement de commencer par là. Ça peut donner l’impression de ne pas faire grand chose, mais la progression est solide (et c’est satisfaisant quand on commence enfin à s’attaquer aux composants plus centraux).

+5 -0

J’imagine que ça doit être la meilleure approche ;)

Le problème, c’est que même plus tard, on aura toujours le problème de JS.. pourtant habituellement j’aime bien le typage du langage mais là, j’aimerai quelque chose de plus fort / strict à la Java/C#

J’ai entendu parler de Typescript et de la possibilité de faire une transition douce et pourtant ça ne m’inspire pas confiance, vu que rien empêche les devs de foutre du any de partout

+0 -0

@ache : difficile à dire. Ça fait 1 an environ qu’on est sérieusement dessus et ça a fait pas mal de progrès (même si reste des modules bien dégueu encore). Pour donner une idée, la codebase est de l’ordre de 50k lignes. Faut voir que cette durée est pas vraiment représentative de quoique ce soit parce que :

  • c’est pas notre boulot (mais l’état du code nous empêchait de faire notre boulot), donc on fait aussi autres choses à côté ;
  • c’est un code de simulation numérique, donc une grosse part du temps est dans les tests de perfs et des résultats eux-mêmes ;
  • les abstractions qu’on a besoin de construire sont pas triviales en terme de logique, on passe parfois du temps à réfléchir aux maths/la physique derrière sans que le code avance.

J’ai entendu parler de Typescript et de la possibilité de faire une transition douce et pourtant ça ne m’inspire pas confiance, vu que rien empêche les devs de foutre du any de partout

Je connais pas TS ni JS mais vu de loin ça a l’air de ressembler dans l’esprit à ajouter des annotations mypy à Python (en un peu mieux parce que TS n’est pas juste des annotations mais un vrai langage). Et d’expérience, ça apporte un vrai plus. J’ai annoté deux codebases Python de ~5k lignes (et d’autres plus petites), et à chaque fois le simple fait d’ajouter des annotations et se laisser guider par les erreurs a permis de :

  • débusquer des bugs, parce qu’écrire du code correct avec du duck typing dynamique, c’est comme écrire un code C sans UB ;
  • mettre en évidence là où une abstraction aurait du sens mais n’était pas écrite parce que le duck typing est permissif ;
  • améliorer l’UX pour les utilisateurs des libs, parce que les annotations rendent l’API plus clair ;
  • forcer à rendre l’API plus propre parce qu’on se rend compte qu’une fonction dans son état courant aurait des annotations complètement rocambolesques (ce qui veut dire en général que l’utiliser correctement est un vrai bordel) ;
  • améliorer l’expérience pour les développeurs parce que c’est plus facile de refactorer du code quand un système de type est là pour guider ;
  • améliorer l’expérience pour les développeurs (bis) en permettant aux outils statiques (genre autocomplétion) de faire leur boulot parce qu’ils ont plus d’information disponible.
+1 -0

À noter qu’en TS, comme beaucoup de langages, tu peux ajouter un linter pour empêcher certaines choses comme les any.

Couplé à des tests automatiques, ça permet de pousser les devs à bosser plus proprement, avec des outils qui peuvent en plus être intégrés à leurs IDEs/éditeurs pour automatiser une partie du formatage (eslint a par exemple une fonctionnalité de correction automatique avec le flag --fix).

Pour avoir passé environ deux ans à plein temps à faire ce genre de boulot (améliorer du vieux code), voici ce que je peux en tirer.

Le point le plus important, et de très loin, pour améliorer le code, est le facteur humain. Si les équipes en place n’ont pas une volonté réelle d’améliorer les choses (développeurs, décideurs pour financer les modifications « non immédiatement rentables » et les outils), alors tu n’arriveras à rien, si ce n’est générer de la frustration.

Pour ça, tu dois présenter clairement à toutes les personnes concernées ce que vont impliquer les changements, contraintes et surtout avantages. En particulier, c’est primordial de présenter des avantages personnalisés à chaque acteur, ceux qui les touchent directement : amélioration de la satisfaction client et des couts à moyen terme par réduction des bugs et de la durée de maintenance aux décideurs, propreté du code aux devs sérieux, simplicité de développement et moins de bugs aux devs moins sérieux, etc.

D’autre part, il faut accepter que le nettoyage de code, c’est un travail long et sans réelle fin (vu qu’il faut conserver le nouveau code propre).

Ensuite, je rejoins plutôt bien ce qui a déjà été dit.

La technique du « figuier étrangleur » fonctionne bien, et a le gros avantage de permettre de ne pas imposer de toucher à du code qui n’a pas besoin d’évolution. Sur du vieux code, tu as souvent des pans entiers de code qui n’a plus besoin d’évolution et qui fonctionne très bien en l’état, autant ne pas y toucher tant que ça n’est pas nécessaire.

Concernant les tests (unitaires / d’intégration), ça dépend beaucoup de l’état actuel. S’il y en a peu, c’est pas la peine d’espérer une forte couverture de tests à court terme. Une bonne technique est d’en ajouter systématiquement à chaque modification (nouveau code, correction de bug), et d’ajouter un contrôle pour empêcher la diminution de la couverture de code

Souvent un problème du vieux code c’est le formatage qui est devenu complètement incohérent, ce qui rends le code difficile à lire. Ce que je fais dans ce cas, c’est ajouter un outil de formatage automatique avec interdiction (automatique) de merge de code mal formaté (et éventuellement, selon le projet, un reformatage global du projet). Par contre attention, j’ai eu des problèmes avec des reformatages de JS qui cassaient certains codes qui se basaient sur des fonctionnalités antiques de JS non-strict !

Enfin, un outil d’analyse statique (comme Sonar ou un linter quelconque) donne beaucoup de bons conseils pour améliorer le code et éviter d’introduire des mauvais comportements. Ces outils ont souvent besoin d’un peu de configuration, surtout pour éviter de hurler à chaque ligne sur les vieux projets ^^

Mais au final tout ça c’est des outils pour aider les développeurs de (plus ou moins) bonne volonté à améliorer le code de la façon la plus confortable et efficace possible. Si cette bonne volonté n’est pas là, le projet ne pourra pas être amélioré.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte