Source

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

Full commit

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 du développement étant proposé par Pilot Systems, je suis intervenu en tant que développeur.

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

  1. Permettre de diffuser des articles et autres media sur le web
  2. Offrir les outils pour la gestion de la partie rédaction
  3. Proposer des services communautaires
  4. Offrir les outils pour la gestion de la partie communautaire
  5. La gestion des abonnements

Les points 1 et 3 forment le site web, les 2 et 4 forment le «BackOffice Libération». Le site de Libération est un site qui reçoit 20 Millions de visites par mois. L'objectif du projet est d'apporter des améliorations fonctionnelles tout en améliorant la pile d'application en adoptant Django.

Dans la suite je présente à la technologie employé, puis je décrit l'organisation du projet et je dresse un portrait technique de l'ancienne et de la nouvelle architecture du système d'information, pour finir je decris 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 des langages open-source en vogue. Apprécié pour le développement de code glue entre différents module, écrit en C ou en C++, il excelle aussi dans le développement rapide d'application 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 nouveau code.

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

Django

Django est le framework qui a la plus forte progression en terme de popularité et de développement dans le monde open-source ces derniers années. Il emprunte des 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 certains nombre de site et startup notamment feu Pownce et sur le réseau de site du journal Lawrence.

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çu 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 parametre de la requête reçue. Les middleware interviennent directement sur les arguments passée par le conteneur WSGI. Après cette opération la main est passé au module de dispatch des requêtes.
  4. L'«URL Dispatch» se charge d'appeller 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 réponses 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 pluspart des opérations en code python. Un moteur de template existe qui permet de séparer la construction de la réponse et le rendu de l'attribut body de la réponse.
  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 Server 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 explicité dans chaque sous partie.

Méthodologie agile

Le projet fonctionne dans un cadre fixé avec un certains nombre de jalons, mais les contributions pour chaque jalons ne sont pas définitives. L'objectif étant de livrer ce qui fonctionne aux différents jalons et de continuer le travail parallèlement à la gestion du code en production pour produire les fonctionnalités manquantes.

Plusieurs choses peuvent survenir qui va bloquer l'avancée du projet Djaz:

  • Évènement politique, social ou économique qui nécessitent le développement ou la re-configuration de module. C'est l'un de points qu'essaye de tacler la plateforme djaz, en rendant possible la création de nouveau contenant web rapidement.
  • Bugue sur la plateforme, il faut intervenir immédiatement. La réponse peut être gradué comme par exemple retirer la fonction pour ensuite proposer la fonction débogué.
  • Une demande ponctuelle des journalistes. En fonction de la charge de travail et des priorités les demandes sont integrées immédiatement ou à la prochaine bascule.

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

Equipe

L'équipe est composé 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 diffuse des articles et autre media sur le web X     14 Août 2011
Offrir les outils pour la gestion de la partie rédaction   X    
Proposer des services communautaires X     14 Août 2011
Offrir les outils pour la gestion de la partie communautaire X     14 Août 2011
La gestion des abonnements     X  
Gestion des flux partenaire X      

Forge(s)

Initialement le gestion des sources et du projet étaient organisé à 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 suivit des sources se faisait à l'aide de la commande hg log ou d'un outils graphique.

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

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é à l'aide de git et de la forge proposé par github.

Utilisation de mercurial

Durant toute la période pré-bascule nous travaillions avec une branche après la bascule 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 «Décision 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évelopper à 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», demande de fusion. 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 version de la plateforme. Une première bascule a permis de passer le Lot 1 sur la nouvelle plateforme, d'autre bascule viendront compléter.

Ancienne architecture

La solution initiale était basé 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 decrite dans la figure 5.4.

_static/infrastructure.png

Ancienne infrastructure

Architecture cible

La nouvelle solution utilise une pile applicative à base de Python aidé 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é par le reste de l'équipe.

Dashboard de suivit des abonnées payant

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

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é par Django pour afficher des widgets graphique permettant de visualiser la progression. Ceci impliquait d'entamer le lot 3 c'est pourquoi nous nous sommes contenter d'une commande django qui génère un fichier au format csv.

Il m'a fallu concevoir la commande, cela impliquait pas d'autre partie du code hormis le code de transition du lot 3. C'était pour moi l'occasion de me familiariser avec le code du projet djaz ainsi que le code PHP. Il m'a aussi fallut m'adapter au workflow de travail.

Améliorer le worlflow d'assurance qualité

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

Lancement des tests projets et sous-modules

La première étape était de pouvoir lancer tous les tests de la plateforme djaz à l'aide d'une seule commande. La difficulté résidait dans la possibilité offerte par django de lancer les tests de la plateforme uniquement pour un seul «projet django». D'autre part certains sous-modules ont leur propre méthode de lancement de test.

J'ai réaliser 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 prennent 20 minutes sur la machine de préproduction, il m'a fallut évaluer la possibilité de lancer les tests plus rapidement.

Deux solutions existent:

  • Placer la base de donnée en RAM avec comme contrainte de ne pas pouvoir éteindre la machine car il faudrais 1 heure pour recharger la base.
  • Limiter le nombre d'écriture sur disque avec la contrainte que la base de donnée puisse être corrompu 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 pouvons pas courir le risque de perdre la base de donnée quand il faut au moins une heure pour la recharger. C'est une configuration utilisable en développement, car nous utilisons des bases plus légères.

Eviter les regressions fonctionnelles

Les tests unitaires sont efficaces contre certains bugs mais pas tous. Le test des fonctions activés par javascript ne sont pas possible pour cela il faut employer d'autre outils tel que Selenium. Selenium permet le test d'une application à l'intérieur d'un navigateur, ses tests couvrent un plus large spectre fonctionnelle et sont plus réaliste.

Jusqu'à maintenant, les fonctions qui bénéficieraient de cette amélioration n'ont pas été considérés 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 cela un outils mis à notre disposition est django-kong. C'est une solution intermédiaire entre Selenium et les test 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'image

Le Libération possède un reader réalisé en HTML5 qui permet la lecture du journal en ligne. Les images du reader ne sont pas pré-générées pour des raisons de performance. Donc 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 module qui travail 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 la colonne où se trouve des offres promotionnelles.

Cette application contient un unique modèle qui se charge de stocker la configuration de la colonne et ses bloques. En effet une colonne est representé par une table qui contient dans chaqu'une 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 monLibe. Il s'agit d'un point de vue technique concevoir le modèle, les vues ainsi que les templates tags. 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é 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

Mirroir fonctionnelle des dossiers abonnées de l'espace monLibé, 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 suivit du processus de creation des dossiers.

Bilan

La conception, le développement et la maintenance sont aisé par le framework Django, et le Python. Django propose des patrons de conception pour aisé le developpement, tout en laissant assez de liberté pour pouvoir remplacer ou developper de nouvelle fonctionnalité dans le framework. Dans un contexte agile nous procédions par itération de conception de l'application, avec parfois des besoins qui remontait lors de l'utilisation. 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 c'est trouvé renforcé avec l'adjonction de tests. Malgré le fait que je connaissait le Python et le Django, j'ai eu des difficulté pratique 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.