Source

REX 2011 @PilotSystems&Libération / djaz.rst

Djaz

Djaz est le projet de modernisation du système d'information qui propulse l'activité web du journal Libération. L'hébergement, le consulting et une partie du développement étant proposés par Pilot Systems, je suis intervenu en tant que développeur.

Ce système d'information dois répondre à ces besoins:

  1. Diffusion des articles et autres medias sur le web
  2. Outils pour la gestion de la partie rédaction
  3. Proposer des services communautaires
  4. Outils pour la gestion de la partie communautaire
  5. Gestion des abonnements
  6. Gestion des flux partenaires

Les points 1 et 3 forment le site web, les 2 et 4 forment le «BackOffice Libération». Le site de Libération reçoit 20 Millions de visites par mois.

L'objectif du projet Djaz est d'améliorer la pile applicative pour permettre un developpement plus rapide, et plus perenne de nouvelles fonctionnalités.

Dans les paragraphes suivants, je présente les technologies employées, puis décris l'organisation du projet et dresse un portrait technique de l'ancienne et de la nouvelle architecture du système d'information, pour finir je présente l'ensemble de mes interventions sur le projet.

Technologies

Python

Python est un langage dynamique de haut niveau multi-paradigme créé en Europe. Sous une licence similaire à la BSD, c'est un langages open-source en vogue. Apprécié pour le développement de code glue entre différents modules, écrit en C ou en C++, il excelle aussi dans le développement rapide d'applications Web grâce à des types de haut niveau, une bibliothèque standard riche et de nombreuses bibliothèques rendus disponibles par la communauté.

Plus lent qu'un langage compilé, sa lenteur n'est pas un facteur limitant dans le monde Web. Il existe des solutions pour accélérer une application «gourmande» en temps processeur tel que le passage du code critique en C, C++ ou Cython. PyPy est une solution de plus en plus envisagée pour accélérer l'exécution des scripts sans avoir à écrire du nouveaux codes.

Il existe un certain nombre de sites propulsés par Python notamment Youtube, Quora et Disqus. Il est aussi utilisé par la NASA notamment dans le cadre du projet Open Stack.

Django

Django est le framework avec la plus forte progression en terme de popularité et de développement dans le monde open-source. Il emprunte de bonnes pratiques du monde de Ruby-on-Rails pour fournir une plateforme complète de développement de site web. Sous License BSD, il est utilisé par un certain nombre de sites Web et startup notamment feu Pownce et sur le réseau de site du journal Lawrence, le Guardian, le Washington Post.

Il s'agit d'un framework qui implémente le patron de conception Modele-Vue-Controlleur appelé dans le monde Django Modele-Vue-Template.

_static/django_page_rendering.png

Représentation de la vie d'une requête dans un projet Django.

La figure 5.1 décrit la vie d'une requête sur un pile applicative Django:

  1. La requête envoyée par le client est reçue par un serveur compatible avec la norme WSGI.
  2. Le serveur WSGI se charge de présenter l'information de la requête selon le standard et appeler l'application web.
  3. La première étape lorsque l'application web est appelée est la curation des paramètres de la requête reçue. Les middlewares interviennent directement sur les arguments passés par le conteneur WSGI. Après cette opération la main est passée au module de dispatch des requêtes.
  4. L'«URL Dispatch» se charge d'appeler la vue qui doit répondre à la requête en fonction de l'url demandé. Les vues sont associées aux urls à l'aide d'expression régulières.
  5. La vue doit construire la réponse. Des raccourcis dans le framework existent pour les plus communes (html, json, erreur 404 etc.).
  6. La vue utilise une couche d'abstraction vers la base de données qui lui permet de realiser la majorité des opérations en code python. Un moteur de template existe, il permet de séparer la construction de la réponse et le rendu de l'attribut body.
  7. La reponse est retournée au conteneur wsgi après être passée de nouveau par la couche middleware.
  8. Le couche middleware va pouvoir intervenir sur toutes les requêtes.
  9. Le serveur WSGI se charge de renvoyer la réponse au client.

Organisation

L'organisation du projet djaz a évolué au fur et à mesure. Ce travail d'amélioration est expliqué dans chaque sous partie.

Méthodologie agile

Le projet a un certain nombre de jalons dont les contributions pour ne sont pas définitives. L'objectif étant de livrer ce qui fonctionne et de continuer parallèlement à gérer le code en production et la réalisation des fonctionnalités manquantes.

Plusieurs évènements qui peuvent bloquer l'avancée du projet Djaz, peuvent survenir:

  • Évènements politiques, sociaux et économiques qui nécessitent le développement ou la reconfiguration de modules.
  • Bug sur la plateforme, il faut intervenir immédiatement pour corriger l'anomalie.
  • Une demande ponctuelle des journalistes. En fonction de la charge de travail et des priorités, les demandes sont intégrées immédiatement ou à la prochaine bascule.

De fait, en dehors des bascules, les mises en production sont faites régulièrement avec au minimum une mise en production par semaine.

Équipe

L'équipe est composée de 10 personnes.

_static/organisation_djaz.png

Équipe du projet Djaz

Lots

Le découpage est représenté dans le tableau suivant :

Fonction Lot 1 Lot 2 Lot 3 date de bascule
Permettre de diffuser des articles et autres medias sur le Web X     14 Août 2011
Offrir des outils pour la gestion de la partie rédaction   X    
Proposer des services communautaires X     14 Août 2011
Offrir des outils pour la gestion de la partie communautaire X     14 Août 2011
Gérer les abonnements     X  
Gérer les flux partenaires X      

Forge(s)

Initialement le gestion des sources et du projet étaient organisés à l'aide du wiki et du tracker de Pilot Systems. Il était difficile de référencer le code depuis le tracker ou le wiki. D'autre part le suivi des sources se faisait à l'aide de la commande hg log ou d'un outils graphique, ce qui n'était pas optimal.

Le passage au logiciel Trac nous a permis une meilleure gestion du projet en intégrant différents workflow à l'intérieur d'un même outil.

Gestion des sources

La gestion des sources du projet se fait à l'aide du logiciel mercurial. Les sous-modules dont le code est indépendant du projet sont gérés à l'aide de git et de la forge proposée par github.

Utilisation de mercurial

Durant toute la période pré-bascule nous avions travaillé avec une branche. Par la suite nous avons mis en place une seconde branche destinée à recevoir ce qui doit aller en production. Le workflow de travail dans cette nouvelle configuration est le suivant:

  • Acceptation d'un ticket dans la forge Trac.
  • Travail sur le ticket, avec possibilité d'alerter l'équipe avec un status «Decision Needed» pour valider la conception.
  • Demande de revue de code sur la forge trac
  • Revue de code en pair ou par un développeur plus expérimenté.
  • Après review et validation le ticket est placé en status «Ready For Production»
  • Les commits faisant référence au ticket sont appliqués à la branche default depuis mercurial.
  • Le code sera en production lors de la prochaine mise en production

Utilisation de github

Les modules indépendants de la plateforme sont développés à l'aide de git et github.

Le workflow est similaire au workflow de travail avec mercurial/trac excepté que l'on travaille par «pull-request». Lorsque du nouveau code est présent dans la branche «master» d'un projet git il est mis en production automatiquement lors de la mise en production suivante.

La Bascule

La bascule est la période du passage de l'ancienne version à la nouvelle. Une première bascule a permis de passer le Lot 1 sur la nouvelle plateforme, d'autres bascules viendront compléter.

Ancienne architecture

La solution initiale était basée sur la technologie PHP Zend. La pile applicative est décrite dans la figure 5.3.

_static/zendstack.png

Pile applicative du système d'information sous Zend

L'infrastructure qui herbergeait cette solution est décrite dans la figure 5.4.

_static/infrastructure.png

Ancienne infrastructure

Architecture cible

La nouvelle solution utilise une pile applicative à base de Python aidée du framework Django. Elle est décrite dans la figure 5.5.

_static/djangostack.png

Pile applicative du système d'information sous Django

L'infrastructure qui héberge cette solution est celle décrite dans la figure 5.6.

_static/infrastructure_new.png

Nouvelle infrastructure

_static/organisation_sources.png

Organisation des sources

Missions

En tant que développeur dans le cadre d'une méthodologie agile j'avais une relative liberté de conception mais mes choix devaient être validés par le reste de l'équipe.

Dashboard de suivit des abonnées payant

Le dashboard de suivi des abonnées payants est une demande du service marketing, qui a pour objectif de permettre l'analyse de l'impact des campagnes d'abonnement.

L'ancienne plateforme se contentait d'envoyer un mail avec les totaux d'abonnées par type d'abonnements. Une personne se chargeait après réception du mail de remplir un tableau pour permettre une lecture plus facile de l'information et la génération de graphique.

Ma première proposition était de modifier l'administration proposée par Django pour afficher des widgets graphique permettant de visualiser la progression. Ceci impliquait d'entamer le lot 3, c'est pourquoi nous nous avons choisi de crée une commande django qui génère un fichier au format csv. Cette proposition avait l'avantage d'éviter la modification du module qui gère les abonnements. C'était pour moi l'occasion de me familiariser avec le code du projet Djaz, de m'initier au code historique de la plateforme, j'ai pu ainsi intégrer l'équipe Djaz.

Améliorer le worlflow d'assurance qualité

J'ai réalisé un point sur les éléments en place permettant de s'assurer le bon fonctionnement de la plateforme ainsi que sa pérennité en proposant des outils qui capturent un maximum de régressions.

Lancement des tests projets et sous-modules

Premièrement il fallait lancer tous les tests de la plateforme à l'aide d'une commande. La difficulté résidait d'une part dans la possibilité offerte par django de lancer les tests uniquement pour un seul «projet django», d'autre part, certains sous-modules ont leur propre méthode de lancement de tests.

J'ai réalisé un script qui permet de lancer tous les tests en série avec la contrainte que les rapports ne soient pas analysables automatiquement.

Accélérer les lancements des tests

Le lancement des tests était trop long (20 minutes), mon travail a consisté à trouver des solutions pour réduire ce temps.

Deux solutions existent:

  • Placer la base de données en RAM avec comme contrainte de ne pas pouvoir éteindre la machine car il faudrait 1 heure pour recharger la base.
  • Limiter le nombre d'écritures sur disque avec la contrainte que la base de données puisse être corrompue en cas de panne de la machine. Le temps de chargement de la base est de deux heures.

Ces deux solutions sont trop contraignantes pour la machine de préproduction. Nous ne pouvions courir le risque de perdre la base de données vu le temps nécessaire pour la recharger. C'est une configuration utilisable en développement, car nous utilisons des bases plus légères.

Éviter les régressions fonctionnelles

Les tests unitaires sont efficaces contre certains bugs mais pas tous. Le test des fonctions activées par Javascript ne sont pas possibles. Pour y remedier il faut employer d'autre outils, Selenium permet le test d'une application à l'intérieur d'un navigateur. En effet, ces tests couvrent un plus large spectre fonctionnel et sont plus réalistes.

Jusqu'à maintenant, les fonctions qui bénéficieraient de cette amélioration n'ont pas été considérées assez nombreuses pour justifier le développement.

Test de réponse positive

Une autre façon de tester une application est de voir si celle-ci répond le bon code HTTP quand on requête ses urls. Pour ce faire, nous avons à notre disposition le logiciel django-kong. C'est une solution intermédiaire entre Selenium et les tests de Django.

Pour les mêmes raisons que précédemment, cette solution n'a pas été mise en place.

Sécuriser la génération d'images

Le site Libération possède un reader réalisé en HTML5, il permet la lecture du journal en ligne. Les images du reader ne sont pas pré-générées pour des raisons de performance. Deux utilisateurs peuvent enclencher la génération d'une image au même moment et provoquer des erreurs d'écriture.

C'était ma première expérience du développement de modules qui travaillent en parallèle pour le web en utilisant le framework Django. La solution était d'utiliser des locks-fichiers avec un temps de vie pour assurer la reprise sur panne.

Colonne de droite

La colonne de droite est dédiées aux offres promotionnelles.

Cette application contient un unique modèle qui se charge de stocker la configuration de la colonne et ses bloques. En effet cette dernière est représentée par une table qui contient dans chacune de ses les lignes les informations qui nous permettent d'afficher un bloque.

La description UML de ce module est représenté dans la figure 5.8.

_static/libepartnersad.png

Diagramme de classe du module gérant la colonne de droite

Carrier Pigeon

Carrier Pigeon est une application exportant des données après la création ou la mise à jour d'un modèle Django. Ce travail a nécessité des connaissances de Django et de Python.

La description UML de ce module est representé dans la figure 5.9.

_static/uml_carrierpigeon.png

Diagramme de classe du module carrier_pigeon

Carrier Pigeon est une application indépendante dont l'intégration à un projet se fait à l'aide de classe Python de configuration.

Gestion de favoris

Lors de cette mission j'ai du reproduire la fonction bibliothèque de «Mon Libé». Il fallut concevoir le modèle, les vues ainsi que les templates. Ce module est indépendant du reste du code de libération, il est utilisé dans des projets hors Djaz.

La description UML, de ce module, est représentée dans la figure 5.10.

_static/uml_favoris.png

Diagramme partiel de classe du module «favorites»

L'implémentation dans djaz se fait en surchargeant les templates dans le projet Django.

Dossiers à la demande

Miroir fonctionnel des dossiers abonnées de l'espace «Mon Libé», c'est une application propre au projet djaz.

_static/uml_fod.png

Diagramme partiel de classe du module «libefolderondemand»

Il a fallut aussi concevoir une interface graphique pour le suivi du processus de création des dossiers.

Bilan

La conception, le développement et la maintenance sont aisés par le framework Django, et le Python. Django propose des patrons de conception pour faciliter le développement, tout en laissant assez de liberté pour remplacer ou développer de nouvelles fonctionnalités dans le framework.

Dans un contexte agile nous procédions par itération. Cela demande un travail rigoureux de documentation de son code pour permettre de revenir dessus facilement à tout moment. La réalisation de la documentation comme le code c'est fait de manière itérative.

Cette méthode de travail s'est trouvée renforcée avec l'adjonction de tests. Malgré le fait que je connaissais le Python et le Django, j'ai eu des difficultés pratiques concernant le travail en groupe et la gestion des sources. Hormis ce petit bémol, mon expérience a été positive et a renforcé mes convictions quant à l'intérêt du développement Web en Python.