URL: https://linuxfr.org/users/oumph/journaux/il-etait-une-fois-la-procrastination Title: Il était une fois... la procrastination Authors: Benoît Sibaud Date: 2020年05月31日T19:57:59+02:00 License: CC By-SA Tags: linuxfr et redis Score: 84 (TLDR: c’est l’histoire d’un geek qui veut écrire un commentaire et, une chose en amenant une autre, il doit écrire du code, de la doc, déboguer, modifier les données en production, écrire un journal et discuter procrastination.) Étape 1, où une mémoire ressurgit : il était une fois un journal sur [Window Maker 0.95.9](https://linuxfr.org/users/dinomasque/journaux/window-maker-0-95-9-est-sorti-le-4-avril-2020). Cela faisait longtemps que le sujet Window Maker n’avait pas été abordé sur LinuxFr.org, et ceci me rappelle des souvenirs lointains de modération multiple des versions de Window Maker. Étape 2, où l’étiquette n’est pas respectée : logiquement, il suffirait que je clique sur l'[étiquette WindowMaker](https://linuxfr.org/tags/windowmaker/public) pour retrouver l’information que je recherche. Ah... apparemment tous les contenus ne sont pas étiquetés. Alors il suffirait que je me lance dans une recherche manuelle direct en base de données sur les journaux et les dépêches pour rafraîchir ma mémoire. Étape 3, qui commence avec une simple recherche en base : il y a 15 journaux et 25 dépêches qui contiennent Window et Maker dans leur titre, cela va donc être rapide. Par contre, le titre ne mentionne pas forcément la version. Mais en triant par date, ça devrait suffire pour retrouver les annonces multiples de versions. En même temps, quitte à voir les 40 contenus, autant vérifier qu’ils sont bien étiquetés. Étape 4, où je me lance dans l’étiquetage : j’ouvre les 40 contenus pour vérifier qu’ils sont bien étiquetés ; je pourrais vérifier en base directement, mais bon j’avais besoin de retrouver les dépêches portant sur la même version initialement, et puis 40 contenus ça ira vite (pensais-je). Tiens je tombe sur un lien est en erreur. Étape 5, où je tombe sur une dépêche en erreur : bizarre, le lien (pas terrible d’ailleurs [/news/windowmaker](https://linuxfr.org/news/windowmaker) comme adresse) vers la dépêche renvoie un code d’erreur HTTP 500. Retrouvons son numéro en base de données en cherchant par rapport à son adresse. Hein ? Deux résultats, comment ça deux résultats sur une adresse unique ? Visiblement il s’agit d’une dépêche acceptée et une dépêche rejetée, en collision ? OK, il suffit de changer l’adresse de la dépêche rejetée, de toute façon personne ne peut y accéder. Heureusement que c’est un cas unique. ```sql SELECT id, cached_slug, state, created_at FROM news WHERE cached_slug='windowmaker'; +-------+-------------+-----------+---------------------+ | id | cached_slug | state | created_at | +-------+-------------+-----------+---------------------+ | 31527 | windowmaker | published | 2000年03月31日 16:48:49 | | 15470 | windowmaker | refused | 2004年02月18日 07:42:06 | +-------+-------------+-----------+---------------------+ ``` Étape 6, où je vérifie que c’est un cas unique : il s’avère finalement qu’après ma première correction, il reste encore 60 cas de collision sur l’identifiant unique, le [slug](https://fr.wikipedia.org/wiki/Slug_(journalisme)), avec 18 collisions pour le premier cas, 5 pour le second cas, et ensuite deux pour les 58 cas restants. Crotte, zut, flûte, saperlipopette. Bon il faut donc corriger ça aussi. Heureusement que c’est limité aux dépêches. Étape 7, où je vérifie les autres tables : ok l’unicité est assurée ailleurs. Sauf pour deux chemins de comptes utilisateurs. Et quatre chemins de journaux (même titre et même compte donc). Et dix-huit chemins d’entrées de forums. Snif. Je voulais juste écrire un commentaire moi, initialement... Étape 8, où il faudrait revoir le schéma de la base de données : Les créations d’index en base de données suivant le [schéma SQL](https://github.com/linuxfrorg/linuxfr.org/blob/main/db/schema.rb) : - il n’y a pas d’unicité imposée niveau SQL pour les chemins basés sur deux champs différents, comme les liens `/users//liens/`, les journaux `/users//journaux/` et les entrées de forums `/forums//posts/`. - et il n’y en a pas non plus pour les chemins basés sur un seul champ, comme `/forums/`, `/sections/
`, `/sondages/`, `/suivi/`, `/users/` et `/wiki/`. Ça serait probablement facile à faire pourtant. Étape 9, où je m’interroge sur le script de vérification de cohérence de la base de données : pourtant normalement on a deux scripts qui vérifient périodiquement l’état des bases MariaDB (SQL) et Redis. Sauf qu’ils vérifient que tous les `slug` existants correspondent à des données (pour détecter des slugs inutiles) et pas qu’ils sont globalement uniques (un même contenu peut avoir plusieurs slugs, si son titre a changé par exemple, mais on aurait voulu éviter que plusieurs contenus puissent avoir le même slug puisque ça donnerait une collision). On récapitule : je dois corriger un script, faire une migration du schéma des données, nettoyer les infos incorrectes en base de données, écrire mon commentaire initial, et en plus maintenant je me dis que je devrais écrire un journal pour raconter tout ça. Comment j’ai réussi à me générer autant de travail moi ? Je commence à écrire et tester ma série de requêtes type ```sql SELECT cached_slug, COUNT(*) AS cnt, 'forums with same slug' FROM forums GROUP BY cached_slug HAVING cnt> 1; ``` et je redécouvre que c’est en fait plus compliqué que cela. Redécouvre parce que j’aurais dû documenter mieux ce schéma, tiens ça ferait une tâche de plus. Étape 10, où je réalise que c’est plus compliqué : en fait le _slug_ stocké dans chaque table est le _slug_ utilisé par défaut, mais il en existe d’autres possibles, stockés dans une autre table, et du coup l’unicité globale est à la fois sur la table du contenu concerné (par exemple `news`) mais aussi sur toutes les entrées de type `News` de la table friendly_id_slugs. On est donc partie pour des requêtes SQL plus complexes. On peut commencer à dépiler. On peut compléter le script avec des requêtes du type ```sql SELECT S.slug, COUNT(*) AS cnt, 'news with the same slug' FROM (SELECT id AS sluggable_id, cached_slug AS slug FROM news UNION SELECT sluggable_id, slug FROM friendly_id_slugs WHERE sluggable_type='News') AS S GROUP BY S.slug HAVING cnt> 1; ``` Et apprendre que désormais c’est 69 collisions pour les dépêches, 18 pour les entrées de forums, 6 pour les journaux et 2 pour les utilisateurs. Pas besoin de modifier le schéma finalement Suivront aussi de longues heures pour produire un diagramme du schéma SQL (avec draw.io) et pour finir par [le commiter](https://github.com/linuxfrorg/linuxfr.org/blob/main/db/schema.png). Les collisions sont des faux positifs (« vero/véro », « beatrice/béatrice ») sur des anciens comptes (il n’y a plus de caractères accentués normalement dans les _slugs_) ou des envois quasi simultanés ou des reliquats d’opération précédant la migration en Ruby on Rails de 2011. Au passage je retrouve l’info que je cherchais initialement et je publie [le commentaire initialement souhaité](https://linuxfr.org/users/dinomasque/journaux/window-maker-0-95-9-est-sorti-le-4-avril-2020#comment-1810072). Je me lance dans la correction de tous les soucis dans les _slugs_ de dépêches, notamment en supprimant de très anciennes dépêches supprimées (jamais publiées, jamais visibles et donc inutiles). Ensuite je revérifie toutes les dépêches avec un petit _curl_, par acquit de conscience, tout en sachant que cela va bien se passer et que cela ne peut plus échouer (« tester c’est douter »). Deux dépêches sortent en HTTP 500... (bim ! étape 11, quand il n’y en a plus il y en a encore) Il s’avère qu’il s’agit de précédentes modifications manuelles et erronées en base de données (probablement suite à la suppression d’un ou plusieurs commentaires), sur l’arborescence des commentaires. J’en profite pour corriger aussi ces soucis-là aussi (histoire d’avoir des arborescences réellement composées de commentaires du même contenu). Enfin j’ajoute des tests dans le script de vérification de la base de données SQL pour détecter les soucis sur les _slugs_ et sur l’arborescence des commentaires. Et au passage un test de plus pour vérifier que le décompte de commentaires par contenu (un champ dénormalisé nodes.comments_count qui stocke localement le décompte des commentaires associés) est bien égal au nombre effectif de commentaires sur le contenu. Il ne reste plus qu’à vérifier le contenu des bases SQL (MariaDB) et Redis avec les scripts, et à nettoyer ce qui dépasse (notamment depuis les suppressions des dépêches un peu plus haut qui ont laissé des résidus devenus inutiles côté Redis). Ainsi qu’à finir de rédiger ce journal. Et là on arrive à la fin de cette histoire dlfpienne (commencée le 10 mai). Si je devais lui donner un titre, je l’appellerais procrastination.

AltStyle によって変換されたページ (->オリジナル) /