Problèmes avec Migrate_from_s3

J’ai deux points à aborder ensuite : Le premier est que la limite est utile, mais elle ne s’applique qu’à l’espace de recherche ; ensuite, je souhaite pouvoir spécifier un nombre maximal de publications à modifier. Je vais donc ajouter un nombre maximal de publications à modifier ainsi qu’une limite pour la requête.

En outre, lors de la spécification de max, il est logique d’être explicite sur ce qui est traité à des fins de débogage. Je souhaite donc rendre la sortie verbeuse si max n’est pas nil — cela permettra aux utilisateurs de valider le processus avant de continuer, car c’est le cas d’usage principal de ce travail.

Je pense que je vais spécifier max comme premier argument et une limite optionnelle comme deuxième, car en réalité, max est l’élément le plus important ; la limite sert simplement à rendre « un seul ping » moins coûteux.

Le deuxième point concerne les non-televersements : les téléversements. Il y a un peu plus d’un an, j’ai essayé de téléverser une vidéo sur le site Discourse où je m’inscrivais, alors que je cherchais désespérément à comprendre comment écrire la migration de Google+ vers Discourse. J’ai alors constaté que ce qui était écrit ressemblait à : https://#{SiteSettings.absolute_base_url}/original/3X/b/a/ba9e06ebc2f4397f26793bb5cd4e169308dd371d.mp4

Aujourd’hui, lorsque je téléverse une vidéo, j’obtiens quelque chose comme : ![file_example_MP4_480_1_5MG|video](upload://caJ9ykkpshw3PFK4464VUIPWJ4l.mp4).

Du moins, lors de mon test le plus récent, migrate_from_s3 a complètement déformé ces URL, les rendant même non reconnues comme des URL, ce qui doit absolument être corrigé. Ensuite, je pense que cette tâche est peu susceptible de rencontrer en pratique ![texte](non-upload-url-to-migrate), donc dans un premier temps, je souhaiterais simplement ajouter la syntaxe markdown de lien autour du protocole magique upload, plutôt que de rendre le regex plus complexe pour gérer les deux cas et le rendre encore plus difficile à lire. Mais je pourrais changer d’avis là-dessus.

Il semble que la balise video ou audio soit ajoutée en JavaScript via une correspondance regex. Je devrai donc copier les regex depuis app/assets/javascripts/discourse/app/lib/uploads.js dans la tâche pour les identifier correctement. J’inclurai la source des regex afin que la prochaine personne qui les trouve sache où les mettre à jour. :stuck_out_tongue:

Ce soir, j’ai trouvé du temps pour travailler sur ce sujet, et j’ai une proposition de pull request (PR) en cours. Elle n’est pas encore terminée ; je sais qu’il reste des bugs. Je ne pense pas avoir modifié le comportement des URL du pseudo-protocole upload: (normales pour les images) à ce stade, bien que j’aie ajouté une vérification de cohérence.

Avec les modifications de cette PR, j’ai réussi à migrer à la fois les téléversements normaux utilisant le pseudo-protocole upload: et les vidéos actuellement référencées explicitement par S3 (ou plutôt Digital Ocean Spaces dans mon cas). J’utilise cette commande pour modifier une seule publication à la fois :

bin/rake uploads:batch_migrate_from_s3[1,1000]

Notez que cela ne dépassera pas les 1000 premières publications retournées de manière quelque peu aléatoire par la requête de base de données ; la limite basse sert uniquement à accélérer la requête tout en migrant une seule publication à la fois, en vérifiant le comportement correct de cette publication, puis en recommençant pour en trouver une autre. Cette commande ne fonctionne ainsi qu’avec la PR sur laquelle je travaille actuellement !

Je continue d’ajouter des sorties de diagnostic au fur et à mesure que je travaille sur ce sujet, et je commence à penser qu’elles sont importantes au-delà du simple développement. Je constate de nombreuses échecs de téléchargement transitoires depuis Digital Ocean Spaces, où certains mais pas tous les téléchargements d’une publication sont migrés. Dans le scénario original, cela se traduirait simplement par l’affichage d’un . et la poursuite du processus, suivi de Done, mais en réalité, la tâche ne sera pas terminée. J’ai dû effectuer cinq ou six passes sur une seule publication avant que tous les fichiers ne soient migrés. (Je ne comptais pas, car je pensais d’abord déboguer un bug local.) Je m’attends à devoir exécuter cette migration à plusieurs reprises avec la même limite jusqu’à ce que les diagnostics soient propres. Par conséquent, j’affiche des progrès verbeux uniquement si max est défini, mais j’affiche des messages d’avertissement utiles dans tous les cas.

Actuellement, j’utilise l’astuce suivante pour pallier les échecs intermittents de téléchargement des espaces Discourse, ce qui, en pratique, a considérablement amélioré mon taux de réussite (trois tentatives ont été entièrement suffisantes sur des centaines de publications migrées jusqu’à présent).

https://github.com/johnsonm/discourse/commit/7dfac12a2ea6ec04ba4e0616b4e0dbd1d806cff7

J’ai également découvert que, pour une raison quelconque, nous nous sommes retrouvés avec des vidéos plus grandes que la limite que j’avais définie lors de l’importation depuis Google+. J’ai dû augmenter temporairement à la fois SiteSettings.max_image_size_kb et SiteSettings.max_attachment_size_kb lors de migrations ponctuelles de quelques vidéos trop volumineuses, dont il n’est pas clair comment elles ont fini sur le site, mais je ne veux pas les casser maintenant… Je ne sais pas si le bug permettant les téléversements trop volumineux provenait de mon script d’importation, de Discourse, ou simplement de ma mémoire des modifications apportées aux paramètres au fil du temps. :wink:

Comme une grande partie de ce que je migre provient d’une importation depuis G+, certaines de mes publications ont échoué aux validations actuelles. J’ai reçu quelques messages du type Échec non géré : Échec de la validation : Désolé, les nouveaux utilisateurs ne peuvent ajouter qu'une seule image dans une publication, et je n’ai pas initialement compris pourquoi ils ne se reproduisaient pas. Il s’avère que les téléversements ont été déplacés avec succès vers le stockage local et qu’ils utilisaient tous le pseudo-protocole upload:, donc le contenu brut n’a pas changé. Cependant, post.save! a échoué avec cette erreur de validation, empêchant post.rebake! de s’exécuter. J’ai donc quelques publications sur 30 000 contenant des images qui doivent être rebakeées ; malheureusement, je n’ai aucune trace de quelles sont ces publications. J’ai maintenant basculé vers post.save!(validate: false) comme autre correctif, de sorte que ce problème particulier ne devrait plus se reproduire. Je suis très heureux d’avoir fait en sorte que la migration s’arrête en cas d’erreurs non gérées, car sinon cela aurait potentiellement causé beaucoup plus de dégâts que quelques publications.

Pour maintenir mon site fonctionnel, y compris la livraison des notifications, tout en exécutant la migration, je ne veux pas saturer les files d’attente Sidekiq. Je sais que nommer les choses est l’un des deux problèmes les plus difficiles en informatique, avec l’invalidation du cache et les erreurs de décalage de un, mais je propose DISCOURSE_MIGRATION_MAX_ENQUEUED en tant que variable d’environnement pour définir le nombre total d’emplacements de file d’attente (pas d’emplacements de tâches) autorisés à être remplis lors de la migration d’un autre élément après un rebake pendant une migration, afin d’éviter de saturer les files d’attente et de permettre au site de continuer à fonctionner. J’ai un correctif qui ajoute cela, avec une valeur par défaut de zéro, pour tous les rebake par publication dans lib/tasks/uploads.rake. Je l’utilise pour ma migration en production.

https://github.com/discourse/discourse/blob/59a761851b9c8786d3a9692f8c595372b0534f77/lib/tasks/uploads.rake

4 « J'aime »