Entropie anthropique

Aller au contenu | Aller au menu | Aller à la recherche

mardi 7 avril 2009

Cappath, appel à volontaires

Bonjour, comme certains savent, je fais un stage au LIP6, et j'ai besoin d'effectuer quelques mesures depuis les utilisateurs finaux des FAI. J'ai donc développé un petit outil qui permet de faire les mesures dont j'ai besoin et me les envoyer. Je vous laisse vous rendre sur la petite page dédiée au projet cappath . Merci d'avance pour votre participation.

vendredi 13 mars 2009

Google Summer of Code 2009

Bonne nouvelle, le GSoC aura lieu cette année, et les organisations peuvent commencer à enregistrer leurs projets. Si vous menez un projet open-source, c'est une occasion à prendre. http://socghop.appspot.com/

mardi 10 mars 2009

Archlinux

Ça y est, je pense avoir trouvé chaussure au pied de mon pc. Je suis passé de Slackware à Archlinux, à priori les concepts KISS sont respectés, on a pas 150 softs inutiles installés de base. Bref, ce qu'il me fallait : du geek mais pas trop. En plus, pas de soucis pour le matériel de mon pc portable, donc vouala grosso modo j'ai gagné un boot plus rapide et un gestionnaire de paquetages avec dépendances.

samedi 10 janvier 2009

Proverbe en vrac #0

Si tu veux pointer du doigt ce qui va mal dans ce monde, il va te falloir beaucoup de mains.

mardi 6 janvier 2009

Ce qui vous attend pour 2009

Tout d'abord bonne et heureuse année, je vais rapidement présenter l'horoscope de l'année à venir:

- Amis: et bien c'est le moment de leur passer vos voeux - Amour: je ne suis pas un Marabout, passez votre chemin pour ça - Argent: facile, vous n'en aurez plus - Santé: ne vous méprenez pas, il fallait lire "sans thé", cf. votre horoscope sur l'argent - Travail: va falloir s'y mettre mais comment l'argent, y'en aura plus - Réussite: apprenez les règles, ça vous occupera - Famille: le jeux des sept familles c'est pas mal non plus

Surtout, restez optimistes, fermez les yeux tout ira pour le mieux dans le meilleur des mondes.

mardi 7 octobre 2008

Suite des appels bloquants huilés en extension C/Ruby

Disclaimer: ce post contient un hippopotame claudiquant et ne dois pas être pris comme une bonne manière d'écrire son code ou penser une architecture.

Bon, je n'ai pas fait de code propre à juste compiler et démarrer pour la preuve du hack, mais voici comment il faut procéder. A noter qu'il faut être un peu au fait des extensions C pour Ruby, je vous laisse chercher sur la toile, il y a peu d'articles mais on les trouve facilement.

Tout d'abord on crée une socketpair avec Ruby (on peut le faire en script).

        int skt1, skt2;
        VALUE sp, s1, s2;
        ID id_socketpair = rb_intern("socketpair");
        ID id_SOCK_STREAM = rb_intern("SOCK_STREAM");
        ID id_Socket = rb_intern("Socket");
        ID id_UNIXSocket = rb_intern("UNIXSocket");
        ID id_ivar_socketpair = rb_intern("@@socketpair");
        ID id_fileno = rb_intern("fileno");

        sp = rb_funcall( rb_const_get( rb_mKernel , id_UNIXSocket ),
                         id_socketpair,
                         2,
                         rb_const_get( rb_const_get(rb_mKernel, id_Socket ) , id_SOCK_STREAM ),
                         INT2FIX(0));

        s1 = rb_ary_entry( sp, 0 );
        s2 = rb_ary_entry( sp, 1 );

        s1 = rb_ary_entry( sp, 0 );
        s2 = rb_ary_entry( sp, 1 );

        /* get the fileno */
        skt1 = FIX2INT(rb_funcall( s1, id_fileno, 0 ));
        skt2 = FIX2INT(rb_funcall( s2, id_fileno, 0 ));

A partir de là, on peut lire et écrire dans les sockets skt1 et skt2, l'une est à réserver au thread de la librairie C qui bloque, l'autre est là pour le thread principal contenant ruby lui-même. Les lectures / écritures doivent être agrémentées d'un protocole perso, compliqué au possible (puisque vous devez faire attention aux sockets qui craquent, que la quantité de donnée lue est la bonne, la façon de la représenter, les signaux qui interrompent la lecture etc.). Elles servent également de synchronisation si besoin.

Du côté de Ruby, on peut soit tout faire en script avec un appel a la méthode kernel "select". En version C ça donne une boucle avec un truc comme

                        ret = rb_funcall( rb_mKernel, id_select, 4, fds, Qnil, Qnil, INT2FIX(1) );

Avec ret une VALUE qui sera Qnil s'il n'y a rien à lire. Le id_select c'est rb_intern("select"), le fds est un array contenant une des valeurs s1 ou s2 lors de la création de la paire de sockets. Le INT2FIX(1) à la fin, c'est le timeout en secondes.

A bien noter qu'un thread doit écrire et lire dans le même socket, vu qu'on lit d'un côté et écrit de l'autre, parfois on se mélange les pinceaux et on y comprend plus rien. Pour résumer, en C les "seules" choses qu'on a vraiment à faire c'est: avoir un thread qui fasse les appels bloquants si nécessaire (risque de devoir faire de la synchronisation supplémentaire) et signale à travers un protocole. Les parties "socketpair" et "select" écrites en C peuvent être faites en script, seule la partie qui ressort un "int C" après un appel à "fileno" est nécessairement à l'interface des deux langages.

Ouf, on y est, je crois que les gens qui auront suivit jusqu'ici sauront deviner les petits pièges, et le hack très moche qu'un tel workaround représente, mais bon, tant qu'on aura pas de threads systèmes, il va falloir faire avec les d'hippopotames claudiquants :) . A réserver pour les petites quantités de données à copier et les trucs "simples". Autant dire pas souvent ^^.

A noter que j'ai surtout fait se post car j'étais déterminé à trouver un workaround au problème, plus qu'à proposer un truc sérieux. Là, il faudrait que je me mette à lire tout les mécanismes de l'intérieur du Ruby officiel de Matz.

mardi 30 septembre 2008

Appels blocants dans une librairie C pour Ruby

Il est généralement admis qu'en Ruby on ne peut pas faire d'appels bloquants sur une ressource externe à cause des green thread. Pourtant, j'ai remarqué que les threads Ruby se comportaient très bien quand un autre attendaient sur un appel à "Kernel.select" (polling sur des sockets). Je ne sais pas trop par quelle magie cela fonctionne, mais ça ouvre une porte à s'affranchir du problème que j'avais lors des premières versions de Férus. Je vais donc pouvoir faire un thread OS qui s'occupe de copier la donnée dans une socket qui sera lue avec select par Ruby. C'est très hacké, mais ça devrait marcher avec relativement peu d'overhead (une ou deux copies). Je vais tacher de faire une proof of concept et puis après qui sait? une lib? le soucis d'une librairie c'est qu'il faut s'occuper à la place de l'utilisateur de tous les évènements qui peuvent arriver sur une socket. Bref, c'est bizarre, mais ça pourrait me débloquer, et donc permettre d'éviter de griller du processeur pour rien (ce qui rendait les jeu en Férus encore plus lent que Ruby ne peut le permettre).

lundi 22 septembre 2008

Retour à la vie-rtuelle

Et bien il en a fallu peu pour que je reste coincé dans la vie réelle en vacances. Maintenant elles sont finies et je repars pour une sans doute dernière année de cours, dont cinq mois de projet de fin d'études.

Du coup je vais commencer à chercher ce stage ingénieur, si possible entre de l'informatique de réseau, du signal, de la radiofréquences ou des fibres optiques. Pour l'instant mes préférences sont à peu près équilibrées. On verra, avec les premiers cours de chacunes de ces matières, lesquelles m'inspirent le plus. Car pour l'instant je me sens trop curieux. Tout bêtement tout me plaît tant que j'ai l'impression de conduire un projet si possible utile et qui compte un peu comme un défi.

En attendant, j'ai remis les mains dans Férus car j'ai trouvé un "hack" pour faire des attentes bloquantes sans bloquer tous les green threads de Ruby (indice: il faut rajouter une socket et faire du polling avec select dessus), ainsi que démarré un client pour les mesures de Grenouille. Il faudra que je mette à jour l'API ruby pour le site VDM et puis voilà tout pour mes projets geek. Ensuite, je me suis mis un peu à la photo et je dois continuer mes travaux de vocalisation des fables de Lafontaine.

lundi 2 juin 2008

Implémentation de l'API du site "vie de merde"

Peut-être bien que vous en aviez pas rêvé, mais pour une raison quelconque j'avais commencé à utiliser l'API du site vie de merde, un site où les gens peuvent dévoiler leurs désillusions à la face du monde.

Une fois arrivé à mes besoins, j'ai remarqué qu'il ne manquait plus grand chose pour en faire une librairie, par contre je ne me suis pas tué à faire un beau gem, et il manque également la récupération des commentaires ainsi que la récupération des erreurs.

C'est téléchargeable à la forge Ruby, et voici un exemple simple d'utilisation:

require 'vdm.rb'

v0 = VDM.au_pif # marche aussi avec au_hasard, at_random
p v0.text
        # => du texte [...]
v0.vote! :plussoie


v1 = VDM.numero 1234
p v1.index
        # => "1234"
p v1.author
        # => "Muffin"

vlist = VDM.dernieres 10 #recupere les 15 dernieres VDM a la 10eme page
p vlist.collect{|v| v.cat}.uniq
        # => [:inclassable, :sexe, :travail, :sante, :amour, :argent]

Amusez-vous bien !

lundi 26 mai 2008

Imbriquer les templates ERB "à la :render chez rails"

Parfois on a envie de pouvoir profiter du templating ERB fourni dans Ruby pour se faire des bouts de codes, ou pour toutes autres raisons, toutefois, pour ceux que ça intéresse, je les laisse évaluer un template.run dans un autre template ERB pour voir le résultat. Pour s'en sortir, il va falloir utiliser les bindings Ruby. Il y a peut-être une autre façon de faire avec les obscurs "_erbout", mais il y a peu de documentation là dessus. Aussi, devant le défi et le travail sur les bindings, je me suis laissé tenté.

A noter que pour certains j'aurai l'impression de réinventer la roue, je ne suis pas allé vérifier dans la touffe de code de Rails s'ils utilisaient la même technique.

Tout d'abord, et car j'ai la flemme de faire un bel article avec toutes les étapes qui m'ont conduit à cette solution, il n'y aura qu'un gros bloc de code avec la classe et l'exemple (certains auront l'habitude). La classe est nommée Renderer et je n'ai défini que des méthodes de classe. On pourrait faire autrement avec des instances d'une classe, mais bon, ça ne me semble pas le point essentiel.

Le point essentiel est le binding dans Ruby. Un binding, c'est une référence au contexte d'éxecution d'un bout de code. Ainsi, passer un binding permet d'avoir accès à un contexte d'éxécution autre que le langage seul le permet. C'est ce qu'on passe à ERB pour qu'il sache à quoi correspond quel nom de variable, même si le fichier est évalué dans un objet différent.

Le but étant de passer dans un Hash le nom des variables de l'intérieur du template, et de les convertir en ce qui est pointé par la clé, on sent déjà venir le eval. Pour faire simple je veux pouvoir utiliser un sous-template dans mon template en faisant

<%= render(:template_1,{'x' => 42}) %>

Je vais donc itérer sur les élements du hash, la clé me servira de variable à déclarer, et la valeur sera justement la valeur pointée. Je dois en outre éviter de déclarer une variable qui écraserait, soit une méthode, soit une variable de mon algorithme de transformation lui même (ce serait la catastrophe). Pour rendre cette probabilité plus faible, j'ai donc utilisé des underscores, vu que je serai le seul à utiliser mon système de templates, je sais la convention qui est ne pas définir une variable "__trucmuche__" dans les paramètres.

L'élément binding me permet de pouvoir itérer à l'intérieur du hash, et de faire mes eval dans le bloc passé à each et en faisant survivre hors du bloc les valeurs créées par eval.

Après ces mises en garde, je dois ajouter que j'aurai pu faire des tests et générer une exception, mais pour laisser l'importance à l'algorithme, je ne l'ai pas fait. De même, j'ai effectué un appel à eval par paire clé/valeur, mais on aurait pu faire un seul appel en créant une chaîne plus longue (et limitant un peu plus les effets de bords des écrasements de variables)

Pour finir, l'évaluation d'un template ERB se fera avec le binding passé à eval. C'est à dire qu'en cas de valeur manquante, l'interpréteur ruby cherchera une méthode et lévera une erreur. Je définis donc method_missing afin d'éviter le carnage si d'aventure on veut pouvoir rendre optionnel une des variables du template.

Bon, j'espère ne pas vous avoir assommé. Voici le code, comme d'hab questionnez si vous le voulez. En tout cas je n'ai pas cherché à savoir ce que donnerait un template qui sortirai du code à son tour interprétable par ERB, pour générer un template de template de template de ... (je doute que ça marche "out of the box")

require 'erb'

class Renderer
    @@partials = {}

    def self.add_partial(name,str="")
        @@partials[name] = str
    end
  
    def self.render(__name__,__params__=nil)
        __b__ = binding
        __params__.each_key do |k|
            __str__ = %{#{k} = __params__['#{k}']}
            puts __str__ if $DEBUG
            eval  __str__ , __b__
        end
        ERB.new(@@partials[__name__]).result __b__
    end

    def self.method_missing(m,*args)
        puts "missing params or method: #{m}, nil-ed out" if $DEBUG
        nil
    end
end

#simple example
t1 = %q{
    str1 : <%= x %>
}

#calling another partial in a partial
t2 = %q{
str2:
<% values.each do |value| %>
    <%= render(:first,{'x' => value})%>
<% end %>
}

#now test missing functions
t3 = %q{
<%= str.class %>
<% unless params.nil? %>
    there are some params
<% end %>
}

Renderer.add_partial(:first , t1)
Renderer.add_partial(:second, t2)
Renderer.add_partial(:third , t3)

puts Renderer.render(:first , {'x'=>0})
puts Renderer.render(:second, {'values'=>(0 .. 10)})
puts Renderer.render(:third , {'str'=>Array.new})
puts Renderer.render(:third , {'str'=> "ok", 'params'=>Array.new})

samedi 24 mai 2008

Wmii moi itou

Bon, et bien, dans ma quête du tuning de distribution, j'ai essayé Wmii, les concepts de design correspondent mieux à ce dont j'ai besoin que les mamouths du window management, à savoir: des fenêtres qui prennent toute la place, quand elles en ont besoin seulement, pilotable au clavier et facilement scriptable.

Par exemple, pour voir combien de jus il reste dans la batterie, plutôt que de regarder l'uptime, j'utilise

echo -n $(cat /proc/acpi/battery/BAT1/state | grep remaining | sed 's/.*:\s*//') '|' $(date)

à l'intérieur de la fonction status() .

dimanche 18 mai 2008

Evaluation des arguments multiples et des blocs avec l'héritage en Ruby

Ça me servira à la fois de piqûre de rappel quand j'en aurais besoin, et ça peut aider à éclaircir les idées. On oubliera pas de ne pas oublier (oui oui, tout ça, j'insiste) que l'appel à super récupère lui-même le bloc. Ce peut être gênant si on a besoin de faire un yield dans la classe fille en même temps qu'on a besoin d'appeler super. Ceci rend plus difficile le changement de comportement d'une méthode qui detruit des informations quand on lui passe un bloc (par exemple l'ouverture/fermeture automatique des fichiers) : il faut faire son yield à l'intérieur d'un nouveau bloc, selon ce qui passe dans les paramètres du bloc ça peut être plus ou moins facile.

Au niveau des arguments multiples, on oubliera pas de ne pas oublier la différence entre *args et args. Il faut voir ça comme un pointeur sur un objet Array. Également, la classe d'un objet, même quand dans la méthode parente est celle de l'objet hérité, ça pourrait jouer des tours si on fait des tests avec == au lieu de is_a? (je n'ai pas mis dans le test, mais is_a? teste l'appartenance d'un objet à une classe et toutes les classes parentes.

Voici le code qui m'a servit pour tout mettre au clair :

class Test
    def initialize(*args,&block)
        puts args.size
        puts self.class
        yield self if block_given?
    end
end

class SubTest < Test
    def initialize(*args)
        super(*args)
        yield self if block_given?
    end
end

class SubSubTest < SubTest
    def initialize
        super(:un,:dos,:tres) {|l| puts "truc"}
        yield self if block_given?
    end
end

class SubSubSubTest < SubSubTest
    def initialize
        super() do |l|
                puts "sub-truc"
                yield self
        end
    end
end

Test.new(1,2) {|l| puts l.class}
SubTest.new {|l| puts l.class}
SubSubTest.new {|l| puts l.class}
SubSubSubTest.new {|l| puts l.class}

Et voici le résultat brut de décoffrage :

2
Test
Test
0
SubTest
SubTest
SubTest
3
SubSubTest
truc
truc
SubSubTest
3
SubSubSubTest
truc
truc
sub-truc
SubSubSubTest

On notera que le "puts self.class" dans la classe principale rajoute une occurence du texte, j'aurais pû mettre ici (ou équivalent plus bas dans la hierarchie) un "if self.class == Test" ou un "if self.is_a? Test" pour montrer la différence entre les deux.

Si vous avez des questions, questionnez, mais je ne promets rien pour les réponses.

lundi 5 mai 2008

Fin de la publicité sur les chaînes publiques

On sait déjà qui veut sa part du gâteau: Laurent Petitgirard de la SACEM Quelqu'un pour le SNEP D'autres pour la SACD Je sens que comme à la radio, les programmations vont être répétitives et iront enfler les poches de ceux qui n'en ont pas besoin.

Je vous suggère de lire "Le chien qui porte à son cou le dîner de son maître", et vous laisse méditer sur les communiqués précédents.

samedi 3 mai 2008

Ubun-tue

J'ai voulu tester les capacités de la si renommée Ubuntu, du coup je l'utilise depuis environ deux mois. Voici mes impressions.

  • l'installation m'avait parue longue pour ce que c'était, charger un live-cd pour ensuite installer, pourquoi pas mais c'est pas ce qui me serait venu à l'esprit
  • certains paramètrages par défaut étaient invivables, par exemple le driver Synaptics : impossible à configurer correctement (j'ai du le désactiver en éditant le xorg.conf à la main)
  • la carte son n'était pas reconnue dès le départ, sans raison particulière car il "suffit" d'éditer une configuration alsa (à la main)
  • après un mois, un mois et demi d'usage, les fenêtres s'ouvrent systématiquement en plein écran, alors que je voudrais qu'elles s'ouvrent comme on les a laissées. Impossible de trouver ou configurer ça dans l'ignoble Gnome, je suis arrivé à modifier ce comportement pour Nautilus seulement, en éditant la base de registre Gconf. Malgré tout, le settings a quand même sauté.
  • si on active les "effets jolis" de compiz-fusion, alors le terminal clignote dès qu'il signale une "erreur", c'est à dire qu'il devient invivable d'utiliser Vim dans un terminal (par exemple): si on fait echap une fois de trop le machin vous arrache les yeux, il "suffit" d'installer l'application d'édition des effets de compiz et de trouver la bonne case (je vous laisse chercher)
  • le packaging à la debian qui sépare toujours en 12000 paquets un logiciel, ses headers etc. font que pour compiler un truc, il faut chercher quinze ans les bons headers, mais ça ce doit être une question de goût, perso je pense que la place occupée par les headers etc. est négligeable pour le public visé par Ubuntu et pourraient être livrés avec
  • finalement, mise à jour laborieuse avec la nouvelle version "support à long terme", les settings ont encore sauté, les touches du clavier pour changer le volume ne marchent plus (il y a bien le pop-up carré avec le volume qui s'affiche, mais la barre de volume reste figée), les bips systèmes ont été restaurés, le fuseau horaire a sauté également
  • sans compter les nouvelles applications plus beugguées que les anciennes (au pif, l'aperçu des espaces de travail qui montrent des fenêtres inexistantes), merci le choix des packages
  • les outils d'administrations me laissent perplexe, par exemple l'outil réseau sert à quoi et à qui ? pourquoi on a "scan de ports" dans un cas et "traceroute" dans l'autre, il n'y a aucune cohérence, dans le choix des noms et le placement de ces outils. D'ailleurs ça sert à quoi au lambda, aux "êtres humains" (car Ubuntu c'est Linux for human beings) ? à priori à rien, et pour ceux qui ont besoin de scanner leur réseau, bah en général ils utilisent nmap car on y met les options qu'on veut.

En conclusion, Ubuntu me laisse une impression d'avoir un système qui tourne mais impossible à configurer, tout du moins sans ligne de commande. C'est en contradiction avec la publicité qu'en font ses fan-boys. Pour avoir déjà utilisé OpenSuse ou Mandrake (c'était pas encore Mandriva), j'dois dire qu'Ubuntu est encore loin derrière les standards d'il y a deux ou trois ans. En tout cas je ne la recommanderai pas à un débutant, et non plus à un développeur. A la limite KUbuntu ou XUbuntu (donc sans Gnome) pourrait être moins pire, mais ne comptez pas sur moi pour faire le test. D'ici la fin du mois, Ubuntu giclera. Ça tombe bien, la nouvelle Slackware est sortie, et je dois aussi tester ArchLinux et Frugalware.

Oui, Ubuntu "just works", c'est à dire qu'il marche à peine.

vendredi 2 mai 2008

Kylie Minogue décorée par Albanel

Et oui, Lundi 5 Mai 2008, Kylie Minogue recevra l'insigne de "Chevalier dans l'ordre des Arts et des Lettres". Consécutivement à d'autres artistes émanants de l'industrie pure et dure (Bob Dylan, Meryl Streep et Uma Thurman). A quand Madonna ou Britney Spears pour leur passion des enfants? Bienvenue à la Cour.

http://news.bbc.co.uk/2/hi/entertainment/7380789.stm http://www.culture.gouv.fr/culture/actualites/index.htm