Parlons un peu de rack :)
Utilisé par rails et de nombreuses autres applications ruby afin de pouvoir être lancées par une large majorité de serveurs web (mongrel, unicorn, ...) rack est particulièrement puissant.
La création d'une première application est on ne peut plus simple.
Dans un fichier test.rb :
Exécutez votre application avec la ligne de commande suivante :
rackuptest.rb
Simple mais efficace :)
Bien évidemment il faut ajouter des librairies à cela afin d'avoir quelque chose de plus puissant.
Maintenant découvronr autre chose : les middlewares.
En effet rack peut embriquer les méthodes call et ainsi vous permettre d'exécuter du code juste après l'initialisation de rack. Ou bien juste avant l'exécution du code de votre page.
Le développement d'un rack ressemble fortement à celui d'une tâche rack "normale".
Voici un exemple de middleware vous permettant d'ajouter, juste avant la balise
, le temps d'exécution de la page.
Dans un fichier response_timer.rb
classResponseTimerattr_reader:message,:app</p><p> def initialize(app, message = "Response Time") @message = message @app = app end</p><p>defcall(env)start=Time.nowstatus,headers,response=app.call(env)stop=Time.now</p><p> body = '' response.each { |part| body << part } index = body.rindex('</body>')ifindexbody.insert(index,"<!-- #{message}: #{stop-start} -->\n")headers["Content-Length"]=body.length.to_sresponse=[body]end[status,headers,response]endend
En revanche, nous allons maintenant avoir besoin d'un fichier de configuration pour rack, afin de pouvoir définir quel middleware nous incluons.
Nous devons pour cela créer un fichier nommé config.ru
Nous incluons les deux librairies que nous venons de créer. Notre application et le middleware
Avec la méthode "use", nous ajoutons le middle à ceux natif à rack
Nous exécutons notre application
Comment ce middleware fonctionne-t-il ?
Comme votre application ! :)
Vous constaterez que les deux ont une méthode call. Et que les deux retournent un tableau contenant status, headers et réponse.
La seule différence entre les deux étant cette ligne :
status,headers,response=app.call(env)
Dans le middleware :
Grace au app.call, nous appellons le middleware suivant. Et ce, jusqu'à ce que nous arrivions au bout de la chaine : notre classe "test".
Nous calculons donc assez aisément le temps d'exécution de notre application. Il nous suffit de faire la différence entre le timestamp avant l'exécution de cette méthode et après.
Et comme nous avons accès au contenu de la page retournée même après l'exécution de la méthode, nous pouvons y ajouter un commentaire juste avant la balise (si elle existe) contenant le temps d'exécution de la page.
Et dans rails ?
Comme dit plus haut, toute application rails tourne avec rack. Il est donc tout à fait possible d'ajouter notre middleware dans votre application.
Dans rails, les middlewares sont à ajouter dans le fichier config/environment.rb.
Le middleware Rack::Lock est le tout premier à être exécuté (vous pouvez avoir la liste de tous vos middlewares avec rake middleware).
Nous exécutons donc, juste avant celui-ci, le calcul du temps d'exécution de notre page :)
Trois méthodes vous permettent d'ajouter de nouveaux middlewares :
config.middleware.use - Le middleware sera ajouté à la fin de la pile
config.middleware.insert_before - Le middleware sera ajouté avant celui passé en premier paramètre
config.middleware.insert_after - Le middleware sera ajouté après celui passé en premier paramètre
Vous pouvez également supprimer un middleware précédemment ajouté : config.middleware.delete
Et remplacer un middleware par un autre : config.middleware.swap
Par ailleurs de nombreux middlewares sont disponibles en Open Source. Vous en trouverez une liste sur le wiki de rack.
Ainsi que dans le projet rack-contrib.