Python et le Data-Driven programming

Gabès Jean ( 16 Dec 2009 ) blog Talk /

Suite au post d'un journal sur linux-fr concernant Shinken et l'avenir de Nagios (http://linuxfr.org/~naparuba/29141.html) certains m'ont demandé pourquoi j'ai choisi le Python (www.python.org) pour Shinken.

  • J'ai répondu que 80% du choix était dû à mon goût perso
  • 20% pour les qualités du langages sur la résolution du problème
    • Les 20% sont en fait le module Pyro (http://pyro.sourceforge.net/) pour les objets distants (un peu comme Corba, mais autrement plus simple à utiliser et plus dynamique (pas de déclaration de squelette)).

    NOTE 2021: en fait j'ai enlevé Pyro au fil du temps, mais il m'a fait gagné beaucoup de temps au début en effet

Et les 80% restant?

On peu un peu se demander ce qu'il y a dans les 80% restant. Outre le fait que le langage ne pique pas les yeux (et évite les nœuds ... au cerveau), et qu'il a d'intégré un module pour la gestion des pools de process (lancement des checks en parallèle), il a de réelles qualités sur son dynamisme qui permettent d'utiliser une vaste panoplie de paradigme de programmation. Il ne les fait pas tous bien entendu (genre la programmation logique (et le prolog)), mais il permets déjà d'utiliser les principaux:

  • programmation itérative et récursive
  • programmation orientée objet
  • programmation orientée aspect (decorator)

Bon c'est bien, mais le rapport avec la choucroute il et où? Et bien suivant la situation, avec Python on peut choisir, c'est plutôt sympa. Lorsque vous gérez des graphes, le récursif s'impose de lui même (ou alors vous être vraiment tordu...), en règle général c'est de l'objet, et dans quelques cas particuliers l'aspect.

Une matrice de création nommée ADN

Concernant l'objet, la création des objets n'est pas classique pour la plupart des types dans Shinken. Nagios utilise des techniques d'héritages sur des objets (hosts/services) qui ont de multiples propriétés (et c'est rien de le dire). Alors m'amuser à faire des constructeurs de 5 lignes non extensibles facilement, non merci. Si c'est pour faire ça, autant rester à faire du C.

C'est là que vient le data-driven (enfin je crois que c'est comme ça que ca s'appelle) : vous décrivez votre objet dans un tableau quelconque, et au lieu de coder ce que vous devez faire pour chaque propriétés, vous faire une boucle sur votre tableau de description pour faire l'action, avec outre le nom de la propriété, les informations dans ce tableau sur quoi faire pour telle propriété. C'est tout (bah oui, c'est tout con, d'ailleurs je l'ai fait avant de savoir comment ça s'appelait...). L'intérêt? Aucun si vote objet a trois pauvres propriétés, mais énorme si elles commencent à devenir nombreuses (genre une bonne vingtaine).

Comme pour la plupart des techniques de programmations, l'intérêt est d'avoir une factorisation des informations. Ici vos propriétés (et les propriétés de ces propriétés...) sont définies dans un seul endroit. Si vous voulez changer, rajouter, supprimer quelque chose, pas besoin d'aller parcourir l'ensemble du code. Celui-ci ne connait pas ce que vous avez mis comme données dans vos tableaux. Il sait les traiter, mais ne connait pas à l'avance ce qu'il y a dedans. Le tableau est une sorte d'ADN de l'objet : c'est sa matrice de fabrication.

Où qu'on le met cet ADN?

Ce qui est embêtant est d'accéder à ce tableau lors de vos traitement. Bien sûr il y a la méthode consistant à le mettre en variable global, mais les variables globales c'est un peu comme le goto : le mal absolu. Mettre le tableau dans chaque objet? Bof, c'est crade, un objet n'a pas besoin d'avoir son ADN d'accroché pour vivre une fois crée (vous utilisez votre ADN vous? Non, vous utilisez les protéines qu'il a permis de fabriquer). Python nous aide ici. Si vous faite objet.class vous obtenez la classe de l'objet. Et oui, une classe est un objet. Et un objet en python peut se voir accrocher des propriétés... genre notre tableau.

Si on rajoute ceci à un héritage de nos objets à une classe "Item" qui va faire le travail de construction, on obtient une fabrique de n'importe quel objet le temps que l'on définisse son ADN dans la classe de l'objet. Pratique non? C'est diablement efficace pour factoriser le code à sa plus simple expression.

Et au final on y gagne beaucoup?

Vous voulez un exemple? Le code de Nagios pour juste la fabrication des objets avec les techniques d'héritages and co prends à lui seul plus de 11K lignes. Shinken dans son entier (architecture distribuée, configuration, envoi dans les bases de données, ordonnancement, etc) en prends un peu plus de 8K. Owned comme dirait l'autre.

NOTE 2021: en effet, par contre purée ce que ça coute chez en temps d'éxécution au run ^^
           un petit language compilé qui me permettrait de faire la même chose? :p

Archives