<?xml version="1.0"?>
<rss xmlns:a="http://www.w3.org/2005/Atom" xmlns:dt="http://xsltsl.org/date-time" version="2.0">
  <channel>
    <title>Yoan Blanc’s weblog</title>
    <link>http://yoan.dosimple.ch/blog/</link>
    <description>The boring weblog of Yoan
	Blanc</description>
    <item>
      <title>Alpage</title>
      <link>http://yoan.dosimple.ch/blog/2011/05/31</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2011/05/31</guid>
      <pubDate>Tue, 31 May 2011 23:59:59 +0200</pubDate>
      <category>Life Alp Master Me</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
I’m doing this again, spending a summer working in the Alp with cows, cheese,
alpine ibexes and everything that come with that. Because there is a balance
with my other life I guess, because it brings a rythm I’m looking for. Some
kind of peace.
</p><p xmlns="http://www.w3.org/1999/xhtml">
After that, I’ll try to go back to school, doing a Master in
Computer Science (because I have no choices in fact) in either the EPFL or the
Universities of Bern, Neuchâtel and Fribourg. I see this as being an exit door
to what I’m currently doing for a living and an opening door to a new world of
opportunities which must not be related to the everywhere Internet.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Many people of my family or friends seem to not follow my moves and not
understanding and seeing the meaning behind them. I can tell you, there is
nothing particular I’m looking for except the thing I know the most, myself.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Going back to the Alp has a strong meaning, the work there is repetitive.
You have to milk, do the cheese every single day no matter how you
are, what the weather is or if something went wrong. You have to do it,
working in rythm with the animals, the nature, the weather, everything
surrounding you. It directs, inhibits my eager of discoveries, knowledge,
questions, novelties, forcing me to focus on what matters. And what matters
isn’t related to myself, it’s what matter for the whole, the bigger stuff I’m
part of.
</p><p xmlns="http://www.w3.org/1999/xhtml">
To be honest with you, working as a Freelance is a way to not be part of
anything.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Now the studies, what’s hidden behind this. I’m only describing the idea I may
have now which won’t be what it’s gonna bring while doing it. It’s again about
going back to something, somewhere. Being humble enough to say, I don’t know
shit and I need to be told because I’m ready to listen and learn, instead of
pretending I know what I, in fact, ignore. Also, if we learned a lot at the
engineering school the focus was really on practice and my theroritical basics
as been missed. Sometimes I can feel that lack and it’s a gap that can be
filed.
</p><p xmlns="http://www.w3.org/1999/xhtml">
I had the opportunity to give some lessons at an engineering school and it might
be something I could do in the future once I’ve learned how to be nice and to
answer kindly to stupid and repetitive questions. They are days where I feel
more like Linus than Richard when it comes to explaining something very simple
to smart people. We need both of them but not everyone likes when you hurt
their feelings.
</p><p xmlns="http://www.w3.org/1999/xhtml">
And the most important thing, maybe is because I can. I don’t know how hard it
will be but I know I can try without worring about money or people that
would be affected by this. (Put here a little “forever alone” rage comic head)
</p><p xmlns="http://www.w3.org/1999/xhtml">
You are who you are, nothing you do, own or make define you.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Retour à l’Alpage, pour la seconde année je vais passer un été au soleil, à
quelques 1800 mètres d’altitude entre traite et fabrication de l’Étivaz AOC.
Peut-être est-ce un moyen de trouver un équilibre dans cette folle vie que mon
travail me fait mener. La suite devant être un retour aux bancs d’école pour
y effectuer un Master.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Pour tout avouer, il n’y a pas forcément de but précis dans mes démarches,
déplacement, changements, expériences si ce n’est de les vivre. J’entends
encore une bonne copine me dire que seul le chemin compte vraiment. Je sais
que ça travaille certains membres de ma famille, mais c’est important de
laisser aller ce genre de choses.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Plus personnellement, et pour me contredire totalement, refaire du connu, se
replonger dans de l’existant ne m’est pas chose aisée. L’excitation de la
nouveauté est tellement forte, enivrante que seul l’aspect du rassurant car
connu n’offre rien en comparaison. J’ai assez peu ce côté jusqu’au-boutiste,
je trouve (et ça n’est qu’un point de vue). Ainsi par cette boucle, j’aspire à
approndir cette capacité à prendre du plaisir dans le perfectionnement, se
perfectionner plutôt que de butiner. Être entier plutôt que superficiel dans
son travail, sa vie. Changer est si facile quand on a commencé, qu’il faut
réapprendre une certaine stabilité.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Les maigres expériences d’enseignement que j’ai pû glâner ces deux dernières
années m’ont plues et vont peut-être devenir une voie envisagable. Autant j’ai
de l’amertûme par rapport à ce milieu autant m’y plonger permettra(it) de
l’apprivoiser d’une certaine manière.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Et vous que faites vous ces 4 prochains mois ?
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Pure PHP web server</title>
      <link>http://yoan.dosimple.ch/blog/2011/04/30</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2011/04/30</guid>
      <pubDate>Sat, 30 Apr 2011 23:59:59 +0200</pubDate>
      <category>PHP Server Socket WSGI</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
    Over a discussion about doing <a xmlns="" href="http://dev.w3.org/html5/websockets/" hreflang="en">WebSocket</a> in PHP on Reddit, I realized that I still had a
    wrong opinion on this language, considering it as being the scripting
    language tied to a web server (commonly mod_php, php-fpm or fastcgi). I can
    also be a scripting language for running tasks, like many web frameworks
    take advantage of. But you can also write your own server in pure PHP,
    working at the UDP/TCP level.
</p><p xmlns="http://www.w3.org/1999/xhtml">
    Let’s build a web server (aka HTTP server).
</p><pre xmlns="http://www.w3.org/1999/xhtml">#!/usr/bin/env php
&lt;?php
$socket = <a xmlns="" href="http://ch.php.net/stream_socket_server">stream_socket_server</a>(
 'tcp://0.0.0.0:8000', $errno, $errstr
);

if (!$socket) {
 echo "$errstr ($errno)", PHP_EOL;
} else {
 while ($conn = <a xmlns="" href="http://ch.php.net/stream_socket_accept">stream_socket_accept</a>($socket, -1)) {
  $request = '';
  while (substr($request, -4) !== "\r\n\r\n") {
   $request .= fread($conn, 1024);
  }
  $response = &lt;&lt;&lt;EOS
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 12

Hello World!
EOS;
  fwrite($conn, $response);
  fclose($conn);
 }
}</pre><p xmlns="http://www.w3.org/1999/xhtml">
    This is pretty much it. As PHP isn’t multi-threaded maybe the <a xmlns="" href="http://php.net/libevent" hreflang="en">libevent</a> library can help
    but I didn’t manage to install it. Or you could fork it
    using the <code>pcntl_fork</code> way. It actually works, badly but works.
</p><p xmlns="http://www.w3.org/1999/xhtml">
    Let’s create a <a xmlns="" href="http://www.wsgi.org/wsgi/" hreglang="en">WSGI</a>
    for PHP. Maybe not.
</p><p xmlns="http://www.w3.org/1999/xhtml">
    I’m now wondering who would use this for real production stuff. It’s not
    close from what exists in the other web servers like Unicorn, Gunicorn, …
    even if they can leverage threads, native code and existing libraries more
    easily I guess. Not an expert though.
</p><p xmlns="http://www.w3.org/1999/xhtml">
    The code is on Github: <a xmlns="" href="https://gist.github.com/949850">pure PHP
    web servers (non-concurrent and concurrent)</a>
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
    Lors d’une récente discussion sur Reddit concernant l’usage de PHP pour des
    <a xmlns="" href="http://dev.w3.org/html5/websockets/" hreflang="en">WebSocket</a>
    ou plutôt son bien fondé, je me suis rendu compte que j’avais encore une
    mauvaise image de ce dernier. En l’associant à son usage premier, couplé à
    un server web (via mod_php, php-fpm, fastcgi, …), on oublie qu’il peut
    servir de langage de script (au même titre que d’autres) et même un peu
    plus. Il est possible d’écrire un serveur TCP/UDP en PHP pur.
</p><p xmlns="http://www.w3.org/1999/xhtml">
    Dans la version simple (<a xmlns="" href="https://gist.github.com/949850">voir le code</a>), le serveur n’accepte qu’une seule connexion à la fois, il n’est donc pas très utile en soit.
</p><p xmlns="http://www.w3.org/1999/xhtml">
    La seconde <em>forke</em>, c’est-à-dire que le script se duplique ce qui permet d’accepter plus de requêtes à la fois mais crée également un nouveau interpréteur PHP par fois (un fonctionnement commun, PHP n’est pas multithreadé). Il y
    a bien des fonctions permettant de se servir de la bibliothèque <a xmlns="" href="http://php.net/libevent" hreflang="en">libevent</a> mais je n’ai pas
    réussi à l’installer. Pour information, <a xmlns="" href="http://www.monkey.org/~provos/libevent/" hreflang="en">libevent</a>
    est une des bibliothèque permettant à certains serveur web de traîter un
    grand nombre de connexions simultanées (<a xmlns="" href="http://www.kegel.com/c10k.html" hreflang="en">C10K problem</a>).
</p><p xmlns="http://www.w3.org/1999/xhtml">
    Ça ne va pas toute à fait m’enlever l’idée de la tête que PHP est un
    langage de template avant tout et permet aussi de faire des choses un peu
    plus poussées. Je demande encore à voir un serveur WebSocket en PHP même si
    techniquement c’est réalisable.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Safer uploads or don’t trust a browser</title>
      <link>http://yoan.dosimple.ch/blog/2011/03/31</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2011/03/31</guid>
      <pubDate>Thu, 31 Mar 2011 14:04:04 +0200</pubDate>
      <category>PHP Python libmagic Security</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
We did tell you to no trust the browser right? Or the user/bot behind it. And to filter, check, sanitize everything that comes from him, her or it.
</p><p xmlns="http://www.w3.org/1999/xhtml">
So you check the basics like <code>GET</code> and <code>POST</code> arguments. And maybe you check the values coming for the cookies as well. But do you check the file uploading? You know that <code>type</code> arguments sent. This how a request look like:
</p><pre xmlns="http://www.w3.org/1999/xhtml">POST /…
…
Content-Type: multipart/form-data; boundary=boundary

--boundary
Content-Disposition: form-data; name="key"

value
--boundary
Content-Disposition: form-data; name="file"; filename="image.png"
<strong>Content-Type: image/png</strong>

…Your PNG image here…
--boundary--
</pre><p xmlns="http://www.w3.org/1999/xhtml">
The <code>Content-Type</code> field is guessed by the browser and most of the time on the file extension. But it can decide to send whatever it wants like application/octet-stream which just says that it’s a binary file.
<p/>
So, you shall not trust it and always verify what you get using the proper tool, like the UNIX command <a xmlns="" href="http://www.darwinsys.com/file/" hreflang="en">file</a> PHP ships <a xmlns="" href="http://www.php.net/manual/en/book.fileinfo.php" hreflang="en">with it</a> and Python has a wrapper <a xmlns="" href="http://pypi.python.org/pypi/python-magic/" hreflang="en">called magic</a>. That how you use it in Python in a WSGI application (using WebOb).
</p><pre xmlns="http://www.w3.org/1999/xhtml">import magic
from webob import Request

def application(environ, start_response):
 req = Request(environ, charset="utf-8")
 <i># sent from the browser</i>
 uploaded_file = req.POST.get("file")
 <i># what we actually got</i>
 guessed_type = uploaded_file.type
 magic_type = magic.from_buffer(uploaded_file.read(1024),
                                mime=True)
 uploaded_file.seek(0)
 <i>"… whatever else …"</i>
</pre><p xmlns="http://www.w3.org/1999/xhtml">
This way you can really white list the file you users are uploading and prevent them for sending you .mov, .doc or whatever when they think they are uploading a new avatar for their profile. True story.
</p><p xmlns="http://www.w3.org/1999/xhtml">
<a xmlns="" href="https://gist.github.com/896241">The code is on github</a>
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
On vous a certainement dit et répété de vérifier tout ce qui provient de vos utilisateurs, juste ? Alors vous vérifiez les <code>GET</code> et les <code>POST</code>, et parfois aussi les <em>cookies</em> mais avez-vous pensé aux envois de fichiers ?
</p><p xmlns="http://www.w3.org/1999/xhtml">
Aha, non ! C’est bien ce que je pensais. En gros, pour faire simple on peut vous faire parvenir n’importe quoi en vous disant que c’est n’importe quoi d’autre. Tiens une image alors que je t’envoie un document <a xmlns="" href="http://fr.libreoffice.org/" hreflang="fr">LibreOffice</a> (c’est comme Office, si si). Et ça se fait très certainement sans en avoir conscience car c’est le navigateur qui rempli cette information et de manière générale il la devine à partir de l’extension du fichier.
</p><p xmlns="http://www.w3.org/1999/xhtml">
C’est pourquoi il est important d’exclure cette donnée et d’aller la repêcher par ses propres moyens. En PHP, par exemple, ça se fait avec <a xmlns="" href="http://www.php.net/manual/fr/book.fileinfo.php" hreflang="fr">finfo</a> qui est très proche de la commande UNIX <code>file</code>, bien connue. Los.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;?php
$file = $_FILES['file'];
<i>// ce que nous donne le navigateur</i>
$guessed_type = $file['type'];
<i>// ce que file nous donne</i>
$finfo = new finfo(FILEINFO_MIME);
$magic_type = $finfo-&gt;file($file['tmp_name']);</pre><p xmlns="http://www.w3.org/1999/xhtml">
Un petit cas concret de problème que nous avons rencontré. Une gif animée enregistrée en tant que jpg dont on désire obtenir une miniature avec Imagick risque de vous donner autant d’images qu’il y a de frames (si bien entendu vous supportez aussi les gif animées, ce que nous faisons).
</p><p xmlns="http://www.w3.org/1999/xhtml">
Et vous éviterez aussi de retrouver trop de bordel dans les avatars de vos utilisateurs.
</p><p xmlns="http://www.w3.org/1999/xhtml">
<a xmlns="" href="https://gist.github.com/896241">Le code se trouve sur github</a>
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Migrating data from and to MySQL</title>
      <link>http://yoan.dosimple.ch/blog/2011/02/28</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2011/02/28</guid>
      <pubDate>Mon, 28 Feb 2011 20:56:00 +0100</pubDate>
      <category>MySQL ETL</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
In the current project I’m working on, we are currently in the process of migrating the old data to their new model, and it’s way more complex that it first seemed. Mostly because the old database is a mess but that not the point here. I want to expose the way we choose to do this, a way that is efficient. It must be a better way, so speak your mind.
</p><p xmlns="http://www.w3.org/1999/xhtml">
At the end this operation will happen once, but during the current development we might be running them a lot while adding new data sets to it.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Let’s dive, on how we import the data into the new database:
</p><pre xmlns="http://www.w3.org/1999/xhtml">LOAD DATA INFILE
 "/tmp/data.dat"
INTO TABLE
 table_name;</pre><p xmlns="http://www.w3.org/1999/xhtml">
That’s very fast, and can be faster if you allow more space for the InnoDB logs.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Now, where does that tmp/data.dat file come from what does it look like. This file has been generated by another request ran on the old database.
</p><pre xmlns="http://www.w3.org/1999/xhtml">SELECT
 id, name, some_value
FROM
 old_table
INTO OUTFILE
 "/tmp/data.dat";</pre><p xmlns="http://www.w3.org/1999/xhtml">
This is a trivial one, recreating a new table with three columns. By default the output format is a tab separated file where NULL has been replaced by \N.
</p><p xmlns="http://www.w3.org/1999/xhtml">
If your old data base — like it’s our case — is still in Latin 1 or 15 (in Europe), using iconv on the .dat file can convert it to, for example, utf-8.
</p><pre xmlns="http://www.w3.org/1999/xhtml">iconv \
 -f iso-8859-15 \
 -t utf-8 \
 /tmp/data.dat &gt; /tmp/data_utf8.dat
mv /tmp/data{_utf8,}.dat</pre><p xmlns="http://www.w3.org/1999/xhtml">
We got tricked by some cp-1252 characters mixed with the Latin 15 ones, beware of those.
</p><p xmlns="http://www.w3.org/1999/xhtml">
And to finish this, two tipps if your old data are too messed up.
</p><p xmlns="http://www.w3.org/1999/xhtml">
You are using text fields in the old data but will use a dedicated table now one so you should use a temporary table for this kind of mapping, i.e. country.
</p><p xmlns="http://www.w3.org/1999/xhtml">
You cannot get all the data at once and need to compute stuff for some rows. In our case moving the pictures to a dedicated table and linking them back afterwards. So we load the data that need to be updated into a temporary table and then perform on update SQL statement to update them all at once, they work like natural joins.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Mon projet actuel consistant à migrer des données presque historiques peu structurées, chaotiques et pleines de surprises vers un modèle plus carré aux contraintes d’intégrités respectées. Pour y arriver, et après divers essais, voici comment nous nous y prenons. Le contexte est simple, une base de donnée MySQL en MyISAM et latin 15 (iso-8859-15) est morphée en une autre devant inclure la première mais permettre plus utilisant InnoDB (pour les contraintes d’intégrité notamment) et UTF-8 (unicode partout, tout le temps).
</p><p xmlns="http://www.w3.org/1999/xhtml">
Dans les solutions explorées, il y a la manière dont fonctionne la commande mysqldump qui produit des INSERT. C’est bien, dès qu’il s’agit d’effectuer des opérations un peu plus complexe sur les données à sélectionner ça en devient plus difficile et il y a des limites quant au nombre d’insertions pouvant être effectué à la fois. Pas assez simple.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Une autre approche aurait été de se reposer sur un outil de <a xmlns="" href="http://fr.wikipedia.org/wiki/Extract_Transform_Load" hreflang="fr">ETL (Extract Transform Load)</a>, très utilisé pour tout ce qui est <em>BI</em> (business intelligence), mais à vue de nez ça ne serait pas assez rapide.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Car même si l’opération, au final, ne sera exécutée qu’une seule fois, au moment de la migration vers le nouveau schéma, en développement il nous faut le faire régulièrement pour nous assurer que les données récentes passent toujours et que le nouveau schéma en cours de migration le fasse.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Et dans une optique purement MySQL, assumant que l’ancienne et la nouvelle base sont indépendantes, l’option a été de se servir des facultés d’export et d’import de MySQL vers le système de fichier avec les commandes :
</p><pre xmlns="http://www.w3.org/1999/xhtml">SELECT …
FROM
 nom de la table
INTO OUTFILE
 nom du fichier;</pre><p xmlns="http://www.w3.org/1999/xhtml">
et
</p><pre xmlns="http://www.w3.org/1999/xhtml">LOAD DATA INFILE
 nom du fichier
INTO
 nom de la table;</pre><p xmlns="http://www.w3.org/1999/xhtml">
Le fichier intermédiaire (les données sont séparées par des tabulations et retours-ligne par défaut) peut être converti en unicode à l’aide de la commande <code>iconv</code> et à coups de <code>tr</code>, il est même possible de se débarasser des quelques caractères <em>cp1252</em> restant.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Et pour tous les cas qui sortent d’un simple <code>SELECT</code> / <code>LOAD</code>, les tables temporaires sont d’une très grande utilité pour effectuer des tables de liaisons (données textuelles vers identifiant, i.e. pays, monnaie, …) ou des importations en plusieurs étapes à l’aide d’un <code>UPDATE</code> sur toute une table (via une très vilaine jointure naturelle, si si).
</p><p xmlns="http://www.w3.org/1999/xhtml">
Au final, je me demande si nous n’aurions pas dû effectuer ce travail là sur la version live du site et amorcer des migrations partielles des données plutôt que de vouloir tout basculer d’un coup. L’avenir le dira.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Si vous avez mieux que cette méthode assez brute, c’est avez grand plaisir que j’en prendrai connaissance.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Posting on a Page from a Facebook Application</title>
      <link>http://yoan.dosimple.ch/blog/2011/01/31</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2011/01/31</guid>
      <pubDate>Mon, 31 Jan 2011 21:12:41 +0100</pubDate>
      <category>PHP Python Facebook Page</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
No revolutions here but since <a xmlns="" href="http://developers.facebook.com/docs/" hreflang="en">Facebook’s documentation</a> always lacks a bit behind because they move too fast, it might be useful to some of you.
</p><p xmlns="http://www.w3.org/1999/xhtml">
First things to know is that pages are owned by users not applications and you can only interact with facebook as an application on the behalf of a user. First thing first, you need <a xmlns="" href="http://www.facebook.com/developers/" hreflang="en">to create an application</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
To act on <a xmlns="" href="http://www.facebook.com/pages/create.php">a Page</a> from an application, the administrator of a Page your application want to administrate must give you the permission to manage his pages. <a xmlns="" href="http://developers.facebook.com/docs/authentication/permissions" hreflang="en">This permission</a> is called, no surprises here: <code>manage_pages</code>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Once the permission is granted, an <i>access_token</i> can be retrieved from <code>https://graph.facebook.com/me/accounts</code> and used from the application to interact with the page.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Nowadays Facebook applications should be made using mostly the <a xmlns="" href="http://developers.facebook.com/docs/reference/javascript/" hreflang="en">JavaScript SDK</a> to login, logout and so forth. That said, ours gonna be static only as we don’t need more.
</p><script xmlns="http://www.w3.org/1999/xhtml" src="https://gist.github.com/804679.js?file=index.html"/><p xmlns="http://www.w3.org/1999/xhtml">
Okay, now you have an application and a page with its <i>access_token</i>. Let’s have fun with the <a xmlns="" href="http://developers.facebook.com/docs/api" hreflang="en">Graph API</a>. Frankly, there isn’t much I can say against the Graph API. It’s a nice example of REST API build upon a very complex data schema.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Let’s submit something.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;?php
$fb = new Facebook(array(
 appId =&gt; null,
 secret =&gt; null
));
$message = 'Hello World!';
$access_token = /* token for the page */;
$fb-&gt;api(
 '/pageNameOrId/feed',
 'POST',
 compact('access_token', 'message')
);</pre><p xmlns="http://www.w3.org/1999/xhtml">
This a simple message, you can make it way more complex. The message will appear as being posted by your application, so pick a cool name.
</p><p xmlns="http://www.w3.org/1999/xhtml">
<a xmlns="" href="https://gist.github.com/804679" hreflang="en" title="source code">This is it.</a>
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Aujourd’hui pas de folie, un simple écrit sur un truc pas assez, ou assez mal, documenté par Facebook lui-même et qui pourra être utile à certains. Comment poster un message, lien, … via un script sur le mur (<i>wall</i>) d’une page ?
</p><p xmlns="http://www.w3.org/1999/xhtml">
La réponse courte, il faut le faire par le biais d’une application dont un administrateur de la page aura préalablement autorisé la dite application de la gérer.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Donc pour commencer, créez une application, cette application sera la personne qui postera sur la page en question.
</p><p xmlns="http://www.w3.org/1999/xhtml">
L’évolution de Facebook a fait qu’aujourd’hui il est recommandé d’éviter FBML (des tags XHTML) au profit d’XFBML qui est, grosso-modo la même chose, mais interpréter côté client par leur bibliothèque JavaScript. Donc, une <code>iframe</code> et une page statique suffiront à notre expérience.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Ensuite le but est de se connecter à l’application, et l’autoriser à gérer vos pages via la permission : <code>manage_pages</code>, ça ne s’invente pas. Une fois autorisée, l’application peut demander à Facebook des jetons d’authentification (<a xmlns="" href="http://tools.ietf.org/html/draft-ietf-oauth-v2-12" hreflang="en">OAuth 2.0</a>) par pages autorisées. Ceci fait, il est temps de s’amuser.
</p><pre xmlns="http://www.w3.org/1999/xhtml">import facebook

access_token = '<i>access token</i>'
obj = {'message': 'Hello!'}

fb = facebook.GraphAPI(access_token)
fb.put_object('pageNameOrId', 'feed', **obj)</pre><p xmlns="http://www.w3.org/1999/xhtml">
Et voilà, c’était plus simple que prévu, non ? Un <a xmlns="" href="https://gist.github.com/804679" hreflang="en">gist</a> contient les codes sources.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>The Lithium way</title>
      <link>http://yoan.dosimple.ch/blog/2010/12/28</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2010/12/28</guid>
      <pubDate>Tue, 28 Dec 2010 22:35:42 +0100</pubDate>
      <category>PHP Lithium Monkeypatching</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
I’m currently working with <a xmlns="" href="http://lithify.me/" hreflang="en">Lithium</a> (aka li3 or Cake 3) mostly for more than a month and would like to share some structure they’ve been putting it and that I like.
</p><p xmlns="http://www.w3.org/1999/xhtml">
I like them because they made that framework so much flexible in a way you can plug anything at almost any places or add — what they call — <a xmlns="" href="http://lithify.me/docs/lithium/util/collection/Filters" hreflang="en">filters</a> to certain key methods or functions to tweak their behaviour at your needs.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Let’s start with the mentioned filters. A filter will wrap the body of a (static) function or method and let you act before / after the initial work, very much like monkeypatching.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;?php
namespace monkey;

class Math extends \lithium\core\StaticObject {
 static function add($a, $b) {
  $params = compact('a', 'b');
  return static::_filter(__FUNCTION__, $params, function($self, $params) {
   extract($params);
   return $a + $b;
  });
 }
}

Math::add(2, 2); <i>// 4</i></pre><p xmlns="http://www.w3.org/1999/xhtml">
As you can see we are using PHP 5.3 features like <a xmlns="" href="http://php.net/namespace" hreflang="en">namespace</a>, <a xmlns="" href="http://php.net/manual/en/functions.anonymous.php" hreflang="en">closures</a> and <a xmlns="" href="http://php.net/manual/en/language.oop5.static.php">late static binding</a>.
</p><ul xmlns="http://www.w3.org/1999/xhtml">
<li>The namespace enable you to avoid Zend Framework alike naming, here we are in the <code>monkey</code> namespace.</li>
<li>A closure is used to describe the body of the function, what it’s gonna do. Before that PHP had only eval-like function (via create_function) that were very ugly to create and use.</li>
<li>And last but not least, the late static binding lives in <code>static::</code> (which is close to <code>self::</code>) but will always be the class where it’s written and not any sub classes (that’s what <code>self::</code> is for)</li>
</ul><p xmlns="http://www.w3.org/1999/xhtml">
Just in case you didn’t know, PHP 5.2 is <a xmlns="" href="http://www.php.net/archive/2010.php#id2010-12-16-1" hreflang="en">not supported anymore</a>. At least before its <a xmlns="" href="http://www.php.net/archive/2010.php#id2010-12-09-1" hreflang="en">next release</a>. <em>Jamais deux sans trois.</em> (never two times without a third time).
</p><p xmlns="http://www.w3.org/1999/xhtml">
Now, let’s hack this.
</p><pre xmlns="http://www.w3.org/1999/xhtml">
&lt;?php
use lithium\util\collection\Filters;

Filters::apply('\monkey\Math', 'add', function ($self, $params, $chain) {
 extract($params);
 $ret = $chain-&gt;next($self, $params, $chain);
 fwrite(STDERR, "$a + $b = $ret");
 return $ret;
});

use monkey\Math;
Math::add(1, 2); <i>// 3</i>
<i>// stderr: 1 + 2 = 3</i></pre><p xmlns="http://www.w3.org/1999/xhtml">
For those who don’t know, stderr is the error output on UNIX. You can pipe / redirect it to another location using <code>2&gt;</code>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Inside lithium this kind of filter are mostly used in the <a xmlns="" href="http://lithify.me/docs/lithium/action/Dispatcher" hreflang="en">Dispatcher</a>. The Dispatcher is the class that handles all the requests, matching a route with an existing controller. So you can do exactly what you would do with WSGI/Rack/… middlewares.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Methods can aslo be written in a way you can filter them afterwards.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;?php
namespace monkey;

class Tweeter extends \lithium\core\Object {
 function tweet($message) {
  $params = compact('message');
  return $this-&gt;_filter(__METHOD__, $params, function ($self, $params) {
   echo 'tweet: ', $params['message'], "\n";
  });
 }
}

$t = new Tweeter();
$t-&gt;tweet(’Hello’); <i>// Hello</i>
$t-&gt;applyFilter('tweet', function ($self, $params, $chain) {
 $params['message'] .= ' ^YB';
 return $chain-&gt;next($self, $params, $chain);
});

$t-&gt;tweet('Hello') <i>// Hello ^YB</i></pre><p xmlns="http://www.w3.org/1999/xhtml">
Pardon my examples to be simplistic. A great usage of all this are tests. By performing surgerical modification inside your objects, it becomes very easy to tweak everything without bloating the initial object much. I agree that filterable methods or functions aren’t as readable as normal ones.
</p><p xmlns="http://www.w3.org/1999/xhtml">
And because on major thing you do in Object Oriented Programming is to link objects, instances together here comes the last pattern, kind of, you may find into Lithium. I dunno exactly if it’s Inversion of Control or Dependencies Injection. I’ve stayed away from Java a too long time to know.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;?php
namespace monkey;

class MyObject extends \lithium\core\Object {
  protected $_classes = array(
   'math' =&gt; '\monkey\Math'
  );

  protected $_autoConfig = array('classes');

  public function plus1($n) {
   $math = $this-&gt;_classes['math'];
   return $math::add($n, 1);
  }
}

$obj = new MyOject(array('classes' =&gt; array(
 'math' =&gt; '\ape\Math'
)));

$obj-&gt;plus1(2); <i>// 3</i></pre><p xmlns="http://www.w3.org/1999/xhtml">
I always feel silly having such useless example but I hope that you get the point. MyObject isn’t linked to a particular Math class but can use a different one if needed with no code modifications.
</p><p xmlns="http://www.w3.org/1999/xhtml">
By the way, <a xmlns="" href="http://symfony-reloaded.org/" hreflang="en">Symfony2</a> uses something similar with a <code>_class</code> suffix in the options.
</p><p xmlns="http://www.w3.org/1999/xhtml">
From a JavaScript, Ruby or even Python point of view, this is the poor’s man monkeypatching and it involves a really heavy syntax for few gains. As I’m still complaining for every <code>array</code> I have to type, this is no big deal.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Don’t forget to join <a xmlns="" href="irc://irc.freenode.net/#li3" hreflang="en">#li3 on freenode</a>.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Depuis mon retour à la civilisation ultra-moderne, j’ai (re)plongé dans PHP et un framework très intéressant : <a xmlns="" href="http://lithify.me/" hreflang="en">Lithium</a> (ou li3 pour les intimes, voire Cake3 pour qui aurait raté une étape) et aimerait pointer deux, trois éléments qu’il offre.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Étant un touche-à-tout, PHP s’avère rapidement frustrant quand on passe un peu trop de temps à faire mumuse avec Python, Ruby ou JavaScript. J’exècre tout particulièrement le mot-clé <code>array</code>. Heureusement que PHP 5.3 offre tout un <a xmlns="" href="http://www.php.net/manual/fr/migration53.new-features.php" hreflang="fr">tas de nouveautés</a> qui satisfont ma curiosité et pèse dans la balance de la frustration.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Il n’est tout simplement pas possible d’altérer un fonction ou méthode en PHP. Ce qu’on appelle <em>monkeypatching</em>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Lithium met en place un système se basant sur les closures (fermetures, clôtures en français) permettant de filtrer l’exécution d’une fonction (statique) ou méthode.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Un filtre, à la manière un middleware WSGI/Rack/JSGI/…, va permettre d’agir avant et après l’exécution initiale. Ajouter des filters, signifie ajouter des couches concentriques. Le code initial doit être adapté pour offrir cette fonctionnalité, hélas, mais l’aspect positif est qu’il ne devrait pas être nécessaire de modifier certains composants centraux du framework.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Autre point intéressant est qu’une relation logique entre deux classes n’est pas figée. Une table de correspondance  permet de, à la volée, modifié quel classe sera utilisée. Point très, très utile lors des tests pour remplacer un système envoyant des e-mails par exemple par un autre ne faisant rien (autrement dit <em>mocking</em>).
</p><p xmlns="http://www.w3.org/1999/xhtml">
Un simple respet d’architecture, structure pour une flexibilité finale.
</p><p xmlns="http://www.w3.org/1999/xhtml">
<a xmlns="" href="http://symfony-reloaded.org/" hreflang="en">Symfony2</a> utilise, par endroit, la même idée pour l’interchangeabilité des composants mais je n’ai rien vu de similaire aux filtres. J’imagine que le système évènementiel permet d’obtenir des résultats similaires.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Amusez-vous bien, réveillonnez à souhait et n’oubliez pas que PHP 5.2 est tellement <a xmlns="" href="http://www.php.net/ChangeLog-5.php#5.2.0" hreflang="en">2006</a>.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Freelancer, one year later</title>
      <link>http://yoan.dosimple.ch/blog/2010/11/29</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2010/11/29</guid>
      <pubDate>Mon, 29 Nov 2010 20:53:00 +0100</pubDate>
      <category>Freelance Life Work</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
Now that I left the chalet and am back into business, I’d like to share some thoughts about it.
</p><p xmlns="http://www.w3.org/1999/xhtml">
One year ago, I was leaving <a xmlns="" href="http://eboutic.ch/wilkommen" hreflang="de">Eboutic.ch</a> and started being my own boss. Being your own boss means nothing much as you’ll still be working for someone. That someone will just change more often that it was before.
</p><p xmlns="http://www.w3.org/1999/xhtml">
I really never asked me this question before: <em>“Why would someone hire you for?”</em> What I would be doing there was more clear to my mind but the why wasn’t. And the situation is mostly unpleasant.
</p><p xmlns="http://www.w3.org/1999/xhtml">
If you’re doing well and have no problems in either deadline or staffing, then why would you hire a freelancer? No reasons. Obviously, it starts with a messed up situation. Brilliant!
</p><p xmlns="http://www.w3.org/1999/xhtml">
Your clients are in trouble and they need someone to just fix it. To just fix it, nothing more because the urge of a deadline or an already exploded budget (that your salary will blow up even more) doesn’t allow more time. Time is cruxial, always.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Cruxial because, quite often, they need you right on. It is also true with companies but they don’t care much if you don’t work on first day, or week, or maybe month from my experience.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Let’s recap, you’ll join a project that might be late, with no more budget and with no controls of what have been done and no way to have an impact on it because you’re not supposed to do so.
</p><p xmlns="http://www.w3.org/1999/xhtml">
I didn’t sign for this, really!
</p><p xmlns="http://www.w3.org/1999/xhtml">
I might be lucky with the actual project where I’ve got the opportunity to learn a lot on human relationships and project managment, being put in the center of those. And also to teach some stuff, to set up good practices and tools. It’s hard and painful as well but at least here is somewhere I can put my guts in.
</p><p xmlns="http://www.w3.org/1999/xhtml">
There is always something to learn out of anything and being freelance gives me the opportunity to do that more often.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Voilà une année que j’ai déposé les plaques et roule ma bosse. Étant de retour dans le métier après une escapade alpestre, qui était loin de ressembler à des vacances, j’aimerais partager ces quelques pensées.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Quand je me suis lancé à l’eau, la question de pourquoi on allait m’engager ne m’est pas venue à l’esprit. J’entends pourquoi non dans pour quelles compétences allait-on m’engager mais quel contexte allait requérire les besoins d’un externe, moi ou un autre. Un peu idéaliste, l’artiste.
</p><p xmlns="http://www.w3.org/1999/xhtml">
En y pensant, un projet qui va bien, où les gens sont compétents et ne quittent pas le poste n’a pas besoin d’un externe. Un projet qui tient ses délais et son budget n’a pas besoin d’une personne externe. Un projet qui débute n’a pas besoin d’externe car on commence rarement un projet avec une équipe qu’on a pas, ou pas partiellement me semble-t-il.
</p><p xmlns="http://www.w3.org/1999/xhtml">
C’est pourquoi on se retrouve contacter pour des projets qui doivent être prêt pour avant-hier, où le budget a été explosé et dont ce qui a été fait l’a été, parfois, par des cousins des Daltons eux-mêmes (les plus cow-boys d’entre tous). C’est une réalité, pas toujours vraie cependant et heureusement.
</p><p xmlns="http://www.w3.org/1999/xhtml">
J’ai un peu l’impression que je me suis dit que j’allais devenir médecin et côtoyer des gens sains tout le jour. À part chez Festina en son temps, c’est rare.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Donc au fond, si je suis indépendant, à mon compte, c’est que j’aime aller mettre les mains dans le merdier des autres. Petite parenthèse, c’est une très belle analogie au travail à l’alpe où il faut littéralement s’en occuper, de la merde. Et quand il est possible de non seulement la brasser mais réussir à nettoyer un peu la place et bien c’est la victoire, l’accomplissement.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Et ma satisfaction là-dedans est que j’aime ça. J’aime réussir à passer ce cap où les choses progressent, prennent formes et deviennent belles. C’est souvent un combat humain, relationnel et plus rarement technique et là, j’en ai des tonnes à apprendre et découvrire.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Je suis content d’être actuellement au sein d’un projet où j’ai cette opportunité d’apprendre beaucoup tout en apportant tout ce que je peux, ce que j’ai, ce que je suis. Pourvu que ça dure.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Life: unplugged</title>
      <link>http://yoan.dosimple.ch/blog/2010/10/20</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2010/10/20</guid>
      <pubDate>Wed, 20 Oct 2010 12:10:00 +0200</pubDate>
      <category>Life Me</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
As <a xmlns="" href="http://yoan.dosimple.ch/blog/2010/05/05/" hreflang="en">you may know</a>, early this year I decided to live an experience and worked at L'Étivaz, then Le Gros Jable, as a farmer (farmer-helper). My work was focused on the three months we spent at l'Alpage (a chalet in the mountain, at 1824m above the sea) where cheese is made.
</p><p xmlns="http://www.w3.org/1999/xhtml">
One of my goals going there was: <em>to let go</em>. I let everything aside: work, flat, computer, loves and worries. None of these define who you are.
</p><p xmlns="http://www.w3.org/1999/xhtml">
My work usually doesn't require any particular rythm. I can start when I'm ready, stop when I'm bored (or it's finished), eat whenever I'm hungry. Dealing with cows that have to be milked twice a day, milk, cheese fabrication, weather and whatever occurs was a real shift. It's also a daily routine where 80% of what you do has to be done that day at a particular time. This repeatition was far from being boring, surprisingly. You start to master some operations, getting better at them, getting faster, parallelizing what can be. At the beginning everything was very intense in how much attention was required and as the time goes none of them remained as something hard to do. Even cleaning the shit out of where the 43 cows were resting during the day was something that became easy.
</p><p xmlns="http://www.w3.org/1999/xhtml">
What about now? I don't know yet, I'll get back on tracks and catch up with projects I was involved in and try to write about stuff I'm doing to gain visibility. Ain't it right?
</p><p xmlns="http://www.w3.org/1999/xhtml">
As a conclusion, this was a huge experience like many others I did in the past. Surprisingly not the one that created the biggest shock of all. I start learning to go through changes it seems.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Me voilà de retour d'<a xmlns="" href="http://yoan.dosimple.ch/blog/2010/05/05/" hreflang="en">un été à l'alpage</a> du Gros Jable à contribuer à la confection de quelques 225 meules de fromage L'<a xmlns="" href="http://www.etivaz-aoc.ch/">Étivaz AOC</a>. 5 mois passés éloigné d'un ordinateur et de tout ce qui faisait mon quotidien précédemment.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Une très belle expérience où il m'a fallut laisser un quotidien derrière et embrasser un présent rythmé par les bêtes, le fromage et la météo. La vie au chalet est belle, intense et riche. De la triple-crème, au paysage en passant par les visiteurs de passage et les tâches quotidiennes, le temps file comme en très bonne compagnie. À mes temps libres, quelques heures par dimanche, j'ai pu profiter de gravir les sommets alentours : Gummfluh, Rots Hore, La Tornettaz (Para), Le Biolet, La Douve, Le Tarent. On m'a montré où trouver du <a xmlns="" href="http://fr.wikipedia.org/wiki/G%C3%A9n%C3%A9pi" hreflang="fr">genépi</a> (une espèce d'absinthe alpestre) et des edelweiss ainsi qu'à suivre les sentiers des chamois et autres bouquetins pour aller dans les lieux les plus escarpés.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Être tous les jours au milieu des montagnes, de vaches, suspendu au milieu d'une vallée à scruter les pentes en amont à la recherche de troupeaux en déplacement, est très apaisant.
</p><p xmlns="http://www.w3.org/1999/xhtml">
À présent, on va tâcher de reprendre la vie d'avant, <em>tam-tam et computer, du sable et du silicium</em>. Quand, comment, rien de bien défini pour le moment.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>A little bit of fresh air</title>
      <link>http://yoan.dosimple.ch/blog/2010/05/05</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2010/05/05</guid>
      <pubDate>Wed, 05 May 2010 14:10:00 +0200</pubDate>
      <category>Life Me</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
Back in March, I was participating to a ski camp with three classes of 11 years old kids. It was an awesome experience that put a little seed in my mind. This kind of seed that made me moving to Paris and later Oslo but with another motivation this time: working outside.
</p><p xmlns="http://www.w3.org/1999/xhtml">
No more air conditioning, wheel chairs, dual screens, coffee break, cantine, daily standup, weekly meeting, headset, skype calls or who’s-the-hell-broke-the-build mornings. It’d be great to get that body to finally do something (gym doesn’t count and I’m not really into it) and let that full of not-that-important-stuff brain relax a bit.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Via sab.ch, I found some farmers looking for a hand this summer, applied and accepted. This means I’ll know how to milk cows and make cheese by this automn, will let any computer-related activities aside for a while and concentrate on a work that is more meaningful, at least seems to.
</p><p xmlns="http://www.w3.org/1999/xhtml">
I’ll be <a xmlns="" href="http://maps.google.com/maps?f=q&amp;hl=de&amp;geocode=&amp;time=&amp;date=&amp;ttype=&amp;q=E+7%C2%B0+11%27+19.85%22+N+46%C2%B0+25%27+47.08%22&amp;ie=UTF8&amp;om=1&amp;ll=46.416796,7.189693&amp;spn=0.07006,0.154324&amp;t=h&amp;z=13">up there</a>, send me a postcard.
</p><p xmlns="http://www.w3.org/1999/xhtml">
This ends mid-October and I don’t know yet what I’ll do then. Freelancing as I do since December is the logical way but as I know me, I don’t know what’s ahead and it’s a good feeling.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Suite à un camp de ski à Zinal, une mouche m’a piqué. Celle de profiter de mon statut d’indépendant pour vivre une expérience dépaysante, à l’air de la montagne. Le genre de mouche qui m’a fait prendre le large pour Paris ou la Norvège mais dans une autre orientation.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Adieu air conditionnée, pauses café, chaises à roulettes, cantine, meetings, échéances, bugs, IE6, casque audio, … et bienvenue vaches, veaux et fromage. Il est temps de (re)mettre en activité ce corps jeune (tant qu’il l’est) et reposer cette tête qui finit par trop penser et sature de contenus aussi inutiles qu’inintéressants.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Via Sab.ch, j’ai trouvé un petit alpage auprès duquel je pourrai offrir mes services et y apprendre le b.-a.-ba du monde agricol alpin tel qu’il existe toujours en 2010. Départ le 17 mai pour 5 mois de bonheur.
</p><p xmlns="http://www.w3.org/1999/xhtml">
N’hésitez pas avec les cartes postales : 
</p><p xmlns="http://www.w3.org/1999/xhtml">
Yoan Blanc c/o<br/>
Gilbert Henchoz<br/>
rte des Blanchettes 51<br/>
1660 L’Étivaz
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le retour à la vraie vie est prévu mi-octobre et j’imagine que je reprendrai le cours des choses là où elles sont restés. Enfin, peut-être pas, me connaissant je sais qu’il faut laisser les portes ouvertes aux idées.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Going Async</title>
      <link>http://yoan.dosimple.ch/blog/2010/04/24</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2010/04/24</guid>
      <pubDate>Sat, 24 Apr 2010 00:29:00 +0200</pubDate>
      <category>Asynchronous Eventlet Gevent Gunicorn Node.js Tornado Twisted Ruby EventMachine</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
I’ll talk about some back-end stuff for a change, showing what can kill your server especially when it comes to external data (aka I/O) and hopefully how solutions are being found.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Let’s take that simple piece of PHP code :
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;?php
$req = "http://pipes.yahoo.com/pipes/pipe.run?_id=…&amp;_render=php";
$data = unserialize(file_get_contents($req));</pre><p xmlns="http://www.w3.org/1999/xhtml">
It grabs some external content and might take some time to achieve this depending of Yahoo! Pipes. This is where the problem starts to itch. When the server gonna call that page it’ll do mostly nothing but waiting for the external data to arrive.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Using Apache, a process or a thread is spawned, waiting on external data and, more importantly, consuming memory and CPU by just waiting.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Going asynchronous would mean being able to do other stuff, answer to other requests while waiting.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Unfortunately, I don’t know any solutions for that problem in PHP. PHP is designed to be executed as fast as possible and not for doing heavy operations. Big websites that are using PHP use it in general as pure front-end language (for example, the before-Google YouTube).
</p><p xmlns="http://www.w3.org/1999/xhtml">
They are a couple of solutions to go async. Some come from a specific language that is asynchronous by design, like JavaScript (with node.js) or Erlang (to name a few). Ruby can achieve this by using <a xmlns="" href="http://rubyeventmachine.com/" hreflang="en">EventMachine</a> and Python (which I explored more) has a couple of solutions (<em>Twisted</em>, <em>Tornado</em> (coming from FriendFeed, bought by Facebook), <em>Eventlet</em>, <em>Gevent</em>, …). Take this dummy WSGI code:
</p><pre xmlns="http://www.w3.org/1999/xhtml">from time import sleep

def application(environ, start_response):
 start_response("200 OK",
		[("Content-Type", "text/plain")])
 sleep(1)
 return ["Hello, world!"]</pre><p xmlns="http://www.w3.org/1999/xhtml">
The external stuff you’re waiting on is simulated by a <code>sleep</code>, which makes it easy to understand. Up to you to fetch external data that will take a fixed time to arrive (which is the same).
</p><p xmlns="http://www.w3.org/1999/xhtml">
When you run this particular code, a process/thread will be dedicated for that during one second blocking other incoming ones, right? You’ll need as many workers/threads/processes as requests to handle them all in one second. Suboptimal since those particular processes aren’t doing anything special.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Take a look at <a xmlns="" href="http://gist.github.com/376416">some tries</a> I made.
</p><p xmlns="http://www.w3.org/1999/xhtml">
<a xmlns="" href="http://www.eventlet.net" hreflang="en">Eventlet</a> and <a xmlns="" href="http://www.gevent.org/" hreflang="en">Gevent</a>, the more convenient to use <abbr title="in my humble opinion">imho</abbr>, will run each incoming requests into a coroutine (like a sub process) enabling the main process to do something else when some time is available. The only thing to change in the code above is where the sleep function comes from.
</p><pre xmlns="http://www.w3.org/1999/xhtml">from eventlet import sleep
from gevent import sleep</pre><p xmlns="http://www.w3.org/1999/xhtml">
And, of course, to run it using the appropriate server (the one from the library, <a xmlns="" href="http://www.gunicorn.org/" hreflang="en">Gunicorn</a> or <a xmlns="" href="http://pypi.python.org/pypi/Spawning/" hreflang="en">Spawning</a> (Eventlet only)). Those libraries are doing monkeypatching so no code has to be modified in order to become asynchronous. I.e. using <code>urllib.urlopen</code> to fetch external data will not block the whole process. No code changes are required.
</p><p xmlns="http://www.w3.org/1999/xhtml">
<a xmlns="" href="http://www.twistedmatrix.com/" hreflang="en">Twisted</a> or <a xmlns="" href="http://www.tornadoweb.org/" hreflang="en">Tornado</a>, for example, are using a reactor model, which forces you to handle asynchronous code with callbacks. It’s closer to the metal but the learning curve might gives you some headaches. I do love Twisted, but it’s sometimes just too much, really.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Python has another project, running on top of <a xmlns="" href="http://stackless.com/" hreflang="en">Python Stackless</a>, called <a xmlns="" href="http://code.google.com/p/syncless/" hreflang="en">Syncless</a> dedicated to async code. It looks quite promising.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Ruby 1.9 will get coroutines under the name of <a xmlns="" href="http://ruby-doc.org/core-1.9/classes/Fiber.html" hreflang="en">Fibers</a>, until that <em>EventMachine</em> seems the way to go. It looks like super clean <em>Twisted</em> too me. I hope not hurting too much feeling by saying that. (BTW, there is a great article from the <em>SuperFeedr</em> guys: <a xmlns="" href="http://blog.superfeedr.com/open/ruby/ruby-fibers-may-confuse/" hreflang="en">Ruby Fibers may confuse</a>)
</p><p xmlns="http://www.w3.org/1999/xhtml">
One very interesting project, and very young as well, is <a xmlns="" href="http://www.nodejs.org" hreflang="en">node.js</a>. Basically server-side JavaScript. This one is asynchronous by design and totally awesome if you love JavaScript or coming out of hell if you don’t like it. I do like it.
</p><p xmlns="http://www.w3.org/1999/xhtml">
With the web evolving the way it does, where data is coming from multiple sources, heavy or special tasks are delegated to specialized units (SOA), I clearly see this asynchronous idea as an ongoing paradigm shift. Today’s bottleneck is the I/O, most often represented by the database.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Don’t forget that the backend performances aim only to serve more people, faster but 80-90 % of the time is spent on the client side. I’m a frontend guy after all.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Pour changer, je vais parler de backend, de ce qui cause des ennuis et malmène un serveur et les solutions qui sont explorées.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Prenons un code assez simple, qui récupère des données externes, par exemple un pipe Yahoo! ou un flux RSS. Dans la majorité des cas, le temps passé à attendre ces données externes est perdu, ne pouvant être réutiliser pour en faire autre chose, comme par exemple en PHP où, à ma connaissance, aucune solution n’existe.
</p><p xmlns="http://www.w3.org/1999/xhtml">
L’idée de base est de, pendant ce temps d’attente, mettre ce bout de code de côté et en prendre un autre. Ce qui permet pendant que la requête d’Alice est en cours, de s’occuper de celle de Bob. C’est ce qu’on entend par asynchronicité, un système dit non-bloquant où certaines opérations (liées à l’environnement externe) ne bloque pas tout le processus.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Diverses solutions existent, dans différents langages de programmation. Certains sont de part leurs concepts déjà capables de fonctionner ainsi, comme Erlang ou JavaScript. Python et Ruby offrent des moyens d’y arriver également. Jetez simplement un œil <a xmlns="" href="http://gist.github.com/376416">aux bouts de code suivant</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Ce sont tous des applications prenant une seconde pour s’exécuter mais qui, au sein d’une seul processus, peuvent fonctionner de manière non-bloquante et parallèle (sans thread). Une comme dix ou vingt requête en parallèle prendront 1 seconde alors que la manière naïve demanderait autant de processus, threads ou autre que de requêtes faites. Les gains de mémoire vive et de processeur sont drastiques.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Comme vous pouvez le voir, certaines solutions semblent plus élégantes, plus simples. Gevent et Eventlet, par exemple, utilisent les coroutines et viennent modifier les éléments existants, bloquants, par une version tirant partie des coroutines, donc non-bloquante.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Selon moi, il y a ici un réel changement dans la manière d’aborder le développement web aujourd’hui. Les applications se distribuent de plus en plus, déléguant certaines fonctionnalités à des entitées plus spécialisées (SOA), voire même, à d’autres services. À l’heure actuelle ça reste souvant les interactions avec la base de donnée qui requièrent le plus de temps.
</p><p xmlns="http://www.w3.org/1999/xhtml">
En tant que développeur frontend, je ne peux m’empêcher de rabâcher que s’il y a là des pistes intéressantes afin de servir plus de visiteurs, plus rapidement avec le même serveur, de 80 à 90% du temps est occupé côté client.
</p></blockquote>]]></description>
    </item>
  </channel>
</rss>

