mardi 15 février 2011

Understanding Rack


 " Rails 3 est compatible Rack "
 " Sinatra est un framework web basé sur Rack "
 " Padrino est un citoyen Rack "



Ces expressions, nous les rencontrons très souvent sur le net et surtout sur les blogs qui parlent de Ruby et du web. Qu'est ce qu'elles peuvent bien vouloir dire ? 
Pour ceux qui savent pas ce que c'est Rack, ces expressions n'ont aucun sens. Malheureusement.

Expliquer Rack, dire à quoi ça peut servir et comment l'utiliser ou en faire n'ont pas été les motivations pour me placer devant "Blogger" ( parce que je suis tout le temps , ou presque, devant mon ordi ) et écrire cet article.

La vraie raison est une question que j'ai "croisée" sur Twitter. Et cette question c'était : " why rack should matter to .net developers  ?". Tout le "monde" commence à faire du 'Rack'. Google a un framework basé sur Django et sur WSGI (la version Rack pour python). La communauté Microsoft en a quelques uns (frameworks je veux dire) que sont Nancy et Nina

Ces frameworks sont basés sur une approche plus intelligente et plus simple que d'autres mais restent quand même moins classes que Sinatra ou Padrino. 

Ok ! Cool ! Mais c'est quoi Rack ? On aimerait bien savoir.

So What is Rack ?

"Rack est une couche d'abstraction qui se trouve entre les serveurs et les frameworks. Cela apporte une plus grande interopérabilité entre les implémentations de serveurs HTTP et frameworks web."

Euuhhh ! C'est pas encore très clair. Revenons un peu dans le temps et revoyons comment communiquent un client HTTP et un serveur HTTP.

schéma 1 : communication HTTP entre un client et un serveur

Sur ce schéma, nous avons un scénario classique de communication entre un client et un serveur.
Le client envoie une requête HTTP. Elle arrive sur le serveur et passe souvent par toutes les couches de l'application. Après traitement de la requête, l'application répond et le serveur renvoie la réponse au client et tout le monde est content. Sûr ? non. Puisque le serveur a des limites logicielles et matérielles.


Pour ce qui est des limites logicielles, on fera comme si on n'était pas au courant et on se concentre (dans cet article) sur les limites matérielles. 


PS : les 'limites' techniques ou logicielles sont surtout la nécessité d'avoir un adaptateur pour chaque serveur web et pour un chaque framework. Ce qui explique que souvent vous soyez obligés de chercher des hébergeurs pour une certaine technologie.Revenons à notre sujet.


La montée en charge ! vous en avez certainement entendue parler ? Comment éviter ce problème ? Est ce que c'est possible si vous n'avez aucun contrôle sur le serveur ? Ben oui. Par le biais des bonnes pratiques et de la bonne modélisation. Passons.


On arrive très facilement à ses limites quand on fait des efforts inutiles. Mais comment savoir qu'un effort peut être inutile ? Comment décider des actions à effectuer avant même de passer la main à l'application concernée (ça peut être un contrôleur aussi quand on fait du MVC) par la requête ?


Simple il faudra rajouter une couche supplémentaire dans "l'architecture" du serveur applicatif. Cette couche devra décider des opérations à effectuer et aussi à les traiter s'il le faut. Et dans ce cas notre application aura moins de boulot à faire et se "fatiguera" alors beaucoup moins vite.
schéma 2 : middleware installé sur le serveur
Expliquons le schéma 2. Nous avons installé sur notre serveur un middleware qui nous aidera à filtrer les requêtes et n'exécuter que celles que nous jugeons importantes ou nécessaires.


Le fait de monter plusieurs middlewares (au besoin) nous donne l'impression que notre serveur est en quelque sorte un tiroir. D'où l'appellation RACK qui veut, littéralement, dire tiroir.


Pour ce qui est des problèmes matériels et logiciels, nous savons à peu prés comment Rack peut aider.


Passons à la partie code! 


Dans le monde Rack, nous avons deux types d'applications. Certaines sont appelées rack applications et d'autres rack middlewares.


La seule différence entre une application et un middleware rack réside dans le fait que le middleware est une application qui a connaissance des autres applications qui sont autour de lui. Il peut communiquer avec elles. 


Tout objet ruby peut être transformé en une application rack valide. Il suffira que ce dernier puisse répondre à la méthode each. Un middleware rack doit avoir au moins deux méthodes initialize et call.


Installation de Rack :


     gem install rack


Première application Rack => 


Exemple : app.rb


class MonApplication

     def call(env)
        [ 200, {"Content-Type" => "text/html"}, "Hi from Rack"]

     end

end



Pour faire tourner cette application rack on utilisera la commande : rackup mise à notre disposition par la gem rack.


La commande rackup exige un fichier nommé config.ru (ru pour dire Rack Up).


Créons notre config.ru :


require 'app'
run MonApplication


et puis : 


rackup config.ru -p 3000 # => http://localhost:3000




Dans le prochain article, on va écrire un middleware l'utiliser dans notre application. Et dans un troisième article sur Rack, nous allons écrire notre propre version de Sinatra :).