Proton

From mediawiki.org
This page is a translated version of the page Proton and the translation is 100% complete.

Proton permet aux utilisateurs de télécharger un article de Wikipedia au format PDF. Il prend en charge à la fois les impressions de bureau et les impressions conviviales pour les mobiles.

Détails techniques

Proton est un service simple qui génère le PDF en utilisant la bibliothèque Chromium activée par by Puppeteer. Il est formé de deux composants :

  • la file d'attente système qui enregistre toutes les demandes (car la génération de PDF est une tâche qui consomme des ressources et beaucoup de temps)
  • le code du générateur qui indique à Puppeteer d'imprimer la page demandée en tant que PDF.

Proton est structuré comme un service web. Il est écrit en JavaScript et utilise Node.js . Son but est de fournir des PDFs jolis et propres. Sur les wikis Wikimedia, Proton est accédé via le proxy RESTBase. Il utilise la bibliothèque puppeteer-core ; le navigateur Chromium n'est pas livré avec puppeteer-core et doit être téléchargé séparément. La variable d'environnement PUPPETEER_EXECUTABLE_PATH désigne l'emplacement de l'exécutable Chromium.

La meilleure manière de générer le PDF d'un article est d'utiliser la fonctionnalité d'impression en PDF de votre navigateur. Cette méthode fournit les meilleurs résultats et en plus elle nous permet de réutiliser les styles d'impression disponibles à la fois pour les versions bureau et mobile de Wikipedia. Le système ne réalise pas le post-traitement du HTML demandé. Les articles sont imprimés tels qu'ils apparaîssent dans l'aperçu avant impression, dans le navigateur de l'utilisateur. Les PDFs générés sont très similaires (si non identiques) à ce que chacun peut obtenir en utilisant Imprimer en PDF dans son navigateur Chrome. Pour obtenir les meilleurs résultats, Proton désactive JavaScript. C'est fait pour empêcher toute transformation dynamique de contenu, comme le chargement des images lazy-load sur les pages pour mobile.

Pour certains utilisateurs, le PDF qu'ils obtiennent par l'impression dans le navigateur et celui qu'ils obtiennent par le service Proton peuvent être légèrement différents car la configuration des fontes dans le système d'exploitation de l'utilisateur peut avoir des paramètres spécifiques relatifs à l'affichage et au crénage des polices.

Principes de la file d'attente

La file d'attente est le coeur du générateur Proton. Il gère le flot de chaque tâche au travers de la logique attente/traitement/expiration. Chaque tâche de la file d'attente peut prendre deux états - 'en attente' et 'en cours de traitement'. Le système de la file d'attente ne permet pas uniquement d'exécuter une quantité de tâches en parallèle, mais il gère aussi le dépassement du temps d'exécution ainsi que l'annulation des tâches. A cause de la complexité de la file d'attente, nous avons dû implémenter une solution qui nous permette de :

  • limiter le nombre de tâches en attente
  • rejeter les tâches en attente après un délai prédéfini
  • limiter le nombre de tâches de génération en cours (car la génération du PDF demande beaucoup de ressources)
  • d'avoir un filet de sécurité pour rejeter les tâches de génération qui prennent trop de temps
  • d'essayer d'annuler la tâche lorsque la requête est abortée afin d'économiser des ressources, et ce quelque soit l'état de cette tâche (traitement/génération).

La gestion de la file d'attente est basée sur les promesses de Bluebird , et utilise la fonctionnalité d'annulation détaillée ci-dessous .

Le moteur de rendu

Le générateur est une simple façade pour accéder à la méthode page.pdf() de la bibliothèque puppeteer. Le générateur a la charge de la configuration de l'environnement Chromium et de la fenêtre d'affichage du navigateur appropriés, en demandant la page Wikipédia, en appelant la fonction page.pdf() . De plus il garde un oeil sur le processus du navigateur. Chaque génération commence par la création d'une instance Chromium et une fois la génération terminée, le processus Chromium disparaît. Pour économiser des ressources, et pour garder notre système en bon état, le générateur demande à Chromium de s'arrêter et si pour quelque raison le navigateur doit encore traiter la requête, il enverra le signal SIGKILL au processus du navigateur pour s'assurer qu'il n'utilise plus le processeur ni la mémoire.

Fonctionnalités supplémentaires

Lorsqu'une tâche échoue parce que la file est pleine ou que les travaux dépassent le temps maximal autorisé pour l'exécution - et ce quelque soit l'état - , alors le service Proton retourne une réponse de service indisponible 503 Service Unavailable avec l'entête Retry-After . L'entête Retry-After sert au partage de charge pour écarter un noeud Proton donné afin qu'il puisse terminer de traiter les tâches en cours. Le système initialise l'entête Retry-After avec la valeur du praramêtre de configuration app.config.render_queue_timeout. Après ce temps, toutes les tâches en cours doivent être terminées, et le système doit être en mesure de reprendre en charge de nouvelles tâches.

Contournements connus

Proton utilise la fonctionnalité d'annulation de BBPromise. La fonctionnalité d'annulation est désactivée par défaut; pour activer la promesse d'annulation, BBPromise.config() doit être appelé avec l'indicateur cancellation:true . Le raison est que la configuration de BBPromise doit être définie avant que toute promesse ne soit créée. Parce que Proton utilise le Service-runner, et que le Service-runner utilise BBPromises pour tout, même la seule lecture des fichiers de configuration n'a pas été facile à implémenter. La marque cancellation ne peut être initialisée dans l'application Proton, car le code Proton est exécuté après l'initialisation du lanceur de services (Service-runner). De même il ne peut pas être défini dans config parce que le Service-runner utilise les promesses lorsqu'il lit la configuration. Dans la version 2.6.6 du Service-runner on introduit l'utilisation de la variable d'environnement APP_ENABLE_CANCELLABLE_PROMISES, qui doit être initialisée à une valeur plausible. Si la variable d'environnement n'est pas définie, l'initialisation de Proton va échouer avec une erreur.

Pour prendre en charge une grande variété de langues nous vous recommandons d'installer les fontes suivantes durant le déploiement :

  • fonts-liberation
  • fonts-noto
  • fonts-noto-cjk
  • fonts-noto-cjk-extra
  • fonts-noto-color-emoji
  • fonts-noto-extra
  • fonts-noto-mono
  • fonts-noto-ui-core
  • fonts-noto-ui-extra
  • fonts-noto-unhinted

Développement

Le développement se fait dans le dépôt Git du service Proton. La relecture de code se fait dans Gerrit. Voir Débuter avec Gerrit pour créer votre compte. Le service utilise le modèle du projet ServiceTemplateNode et suit toutes les règles de développement du service.

Exécuter les tests

Pour exécuter tous les tests swagger et mocha :

npm test

Pour exécuter tous les tests de couverture :

npm run coverage

Documents techniques

Liens pour les développeurs Proton

Voir aussi

  • PDF export
  • RESTBase : une API de proxy pour mettre en cache ou enregistrer les PDF générés par Proton
  • wikitech:Proton: détails sur la gestion, le déploiement et le flux de données

Contact

Si vous avez besoin d'aide ou si vous avez des questions ou des commentaires, vous pouvez nous contacter sur #wikimedia-infrastructure connecter ou via la liste de diffusion wikitech-l.