Shiny happy people coding

Codons avec le sourire

Mailtrap l’aide au staging

| Comments

Avant chaque mise en production d’un projet, il faut le test dans un environement de staging. Pour avoir un environement le plus proche de notre environement de production, une pratique courante est d’éffectuer un dump de la base de production pour avoir un jeu de donnée complet et valide. Ça nous permet aussi de vérifier que nos migrations ne posent pas de problème, tester quelques pages au niveau de leur performance.

En gros faire plein de test comme si on jouait avec la prod mais sans toucher au donnée de production.

Le plus gros soucis que l’on rencontre et beaucoup d’entre nous l’ont rencontré, c’est l’envoi d’email. Tous les emails copié de la production sont valide et posséde un utilisateur au bout. Si nous envoyons un email réellement cela peut vite être problèmatique. Les solutions utilisées généralement sont les suivantes.

Remplacement de tous les emails de la base de donnée.

Une pratique simple est courant est la tâche qui remplace tous les emails de la base de donnée par des emails possédés par la société. Cette technique marche parfaitement, mais pose quelques problèmes :

  • Il faut penser a toujours faire la modification après chaque copie de la base de production.
  • Il faut mettre à jour son script pour remplacer tous les nouveaux champs qui posséde des emails si on en ajoute
  • Il devient difficile de savoir à qui était réelement destiné l’email initial. On peux ainsi passer à coté de quelques bugs.

Ne plus contacter de serveur SMTP et créer un fichier par email

Avec le framework Ruby on Rails, il est possible de définir que tous les emails envoyés sont mis dans un fichier plutôt qu’envoyer par SMTP. Il suffit de définir un nouveau smtp_delivery

1
ActionMailer::Base.delivery_methods = :file

Cette technique permet d’être sûr qu’aucun email n’est envoyé au client finaux. L’inconvénient de cette technique est le stockage et la lecture des emails. Tous les emails sont stocké sous forme de fichier directement sur le serveur. Il peux donc être fastidieux de connaitre les nouveaux emails envoyés, car ils sont classé par destinataire. On peux ainsi ne pas constater qu’un email est envoyé sous certaine conditions. De même, si votre application est utilisé par des personnes n’ayant pas un accès shell à votre serveur, ils ne pourront pas lire les mails envoyés.

Le mock SMTP

Cette technique est selon moi la meilleure actuellement. Elle consiste tout simplement à emuler un vrai serveur SMTP. Par contre, ce serveur ne transmet pas les emails qu’il reçoit. Il les stocke et vous permet de les consulter dans un client mail classique. Ils sont conservé entièrement.

L’avantage est que n’importe qui peux consulter les emails générés, sans aucune connaissance technique évolués et ils sont conservé entièrement.

A ma connaissance, il existe 3 produits qui permettent cela.

Mailcatcher

C’est un produit open source tres simple d’utilisation. Vous télécharger le gem, vous lancer la commande mailcatcher et c’est fini. Vous avez ainsi un serveur SMTP sur le port 1025 et un client mail sur le port 1080.

Je vous le conseille dans un environement de développement. Il a en plus quelques petits addons comme la notification growl.

Le seul soucis que j’ai rencontré avec est le deployement dans un environement de staging. la commande mailcatcher ne permet pas d’écouter sur toutes les interfaces. Il faut donc mettre un proxy devant pour le rendre accessible à tout le monde. On doit donc le maintenir et le gérer. Cela peux être un peu compliqué juste pour un simple mock. Bien sûr rien ne vous empêche de le faire.

Mailtrap.io

Voici un projet que j’ai découvert que très récement. Le concept est exactement le même que celui de mailcatcher, sauf que vous n’avez plus à gérer l’hébergement vous même. Tout est géré par railsware, l’éditeur de ce service.

Vous créer un compte sur leur site, vous créer un serveur SMTP fictif et c’est fini.

Vous obtenez les informations de connection à ce SMTP. Une fois que vous définissez ces paramètres dans votre application, tous les emails seront envoyé directement à Mailtrap.

Une gestion de collaboration sur les mailbox vous permet d’ajouter vos collaborateur à cette mailbox pour qu’ils puissent voir les emails.

Cette solution est vraiment simple a mettre en oeuvre et très pratique. Petit plus, c’est encore gratuit actuellement. Donc profitez en.

Une journée dédiée à MongoDB

| Comments

mongoFR badges

Le 21 Juin se tiendra à Paris un événement auquel je vous invite à venir. Cet événement sera dédié à MongoDB, le MongoFR.

J’ai la chance de pouvoir proposer une petite conférence sur un retour d’expérience : ma migration de SQL à MongoDB sur Oupsnow. Hormis les développeurs de 10Gen, il n’y aura que des Rubyists.

Selon moi, cette nouvelle technologie qu’est MongoDB est assez prometteuse.

Pour découvrir MongoDB, venez nombreux le 21 Juin !

English translation

PeriodicTimer de EventMachine, le cron simplifié

| Comments

EventMachine est une des meilleures librairies Ruby, tout en étant une des plus sous-estimées et mal connues.

J’ai donc commencé à regarder un peu dans quels cas utiliser EventMachine. La première application que j’en ai trouvé c’est tout simplement le PeriodicTimer.

Son utilisation la plus simple est le remplacement d’une cronjob.

Je m’explique : une cronjob est vraiment une très bonne chose. On peut définir très précisément l’heure à laquelle on souhaite qu’une tâche s’exécute. Celle-ci s’exécute alors à ce moment précis. Cron est vraiment un outil magnifique. Cependant, dans le cas d’une tâche récurrente qui doit être effectuée régulièrement, l’utilisation d’un cronjob peut avoir un gros inconvénient.

Cron n’a aucune gestion de queue. Ainsi on peut se retrouver très simplement avec une quantité astronomique de tâches essayant de s’exécuter en même temps. Votre « load » explose et il faut redémarrer votre serveur. Bien sûr cela n’arrive que si vous lancez une tâche plus fréquemment que son temps d’exécution.

La seule solution serait d’avoir une petite application - comme : jobq - qui gére pour vous un système de queue. Bien sûr, si le fait d’avoir une queue ne sert strictement à rien, cette solution peut être un peu overkill.

L’avantage de PeriodicTimer est que les tâches sont exécutées après un temps défini. Il n’y a aucune gestion d’heure de lancement. Il y a juste un lancement de la tâche après X secondes une fois que la précédente tâche est finie et qu’aucune autre tâche ne soit en cours d’exécution. Cela entraîne effectivement un glissement progressif de l’heure de lancement. Mais globalement, ça ne pose aucun problème. L’important est que la tâche soit exécutée régulièrement. C’est le cas, par exemple dans le cas de récupération de statistique.

Voici un exemple de code qui utilise PeriodicTimer

1
2
3
4
5
6
7
8
9
10
11
12
require 'eventmachine'
require 'timeout'
EventMachine.run {
 EventMachine::PeriodicTimer.new(10) do
   puts "#{Time.now} : I am 10"
   sleep 10
 end

 EventMachine::PeriodicTimer.new(1) do
   puts Time.now
 end
}

Voici la sortie qui est effectuée si on lance l’application pendant 50s.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$ ruby em_periodic.rb
Fri Mar 26 16:07:39 +0100 2010
Fri Mar 26 16:07:40 +0100 2010
Fri Mar 26 16:07:41 +0100 2010
Fri Mar 26 16:07:42 +0100 2010
Fri Mar 26 16:07:43 +0100 2010
Fri Mar 26 16:07:44 +0100 2010
Fri Mar 26 16:07:45 +0100 2010
Fri Mar 26 16:07:46 +0100 2010
Fri Mar 26 16:07:47 +0100 2010
Fri Mar 26 16:07:48 +0100 2010 : I am 10
Fri Mar 26 16:07:58 +0100 2010
Fri Mar 26 16:07:59 +0100 2010
Fri Mar 26 16:08:00 +0100 2010
Fri Mar 26 16:08:01 +0100 2010
Fri Mar 26 16:08:02 +0100 2010
Fri Mar 26 16:08:03 +0100 2010
Fri Mar 26 16:08:04 +0100 2010
Fri Mar 26 16:08:05 +0100 2010
Fri Mar 26 16:08:06 +0100 2010
Fri Mar 26 16:08:08 +0100 2010
Fri Mar 26 16:08:08 +0100 2010 : I am 10
Fri Mar 26 16:08:18 +0100 2010
Fri Mar 26 16:08:19 +0100 2010
Fri Mar 26 16:08:20 +0100 2010
Fri Mar 26 16:08:21 +0100 2010
Fri Mar 26 16:08:22 +0100 2010
Fri Mar 26 16:08:23 +0100 2010
Fri Mar 26 16:08:25 +0100 2010
Fri Mar 26 16:08:26 +0100 2010
Fri Mar 26 16:08:27 +0100 2010
Fri Mar 26 16:08:28 +0100 2010
Fri Mar 26 16:08:28 +0100 2010 : I am 10

On peut constater que la tâche qui doit s’exécuter toutes les secondes le fait bien. Par contre la tâche qui s’exécute au bout de 10 secondes effectue un lock sur le thread. Ainsi la tâche qui s’exécute toutes les secondes attend que le lock soit libéré. Une fois terminée, l’exécution de la tâche toutes les secondes recommence. La tache qui doit s’exécuter toutes les 10 secondes attendra, quand à elle, 10 nouvelles secondes après avoir été terminée.

C’est là une grande puissance de PeriodicTimer. On a facilement une succession de tâche qui ne se marchent jamais sur les pieds. Désormais, je n’utilise plus que

cette solution pour créer des scripts de récupération de données.

Oupsnow 0.5.0 est sortie

| Comments

Ca y est, j’ai presque pris un cycle de release pas trop mauvais. Ainsi après seulement un mois après la version 0.4.1 de Oupsnow, voici la version 0.5.0. Cette version apporte quelque feature, mais marque surtout un moment de stabilité dans le code.

Les nouveautés

  • Ajout d’un filtre sur la recherche des tickets pour ne voir que les tickets fermé ou non
  • Possibilité d’éditer une milestone pour les admin d’un projet
  • Possibilité de définir une milestone comme actuelle. Par défaut, c’est la première milestone créée
  • Possibilité de récupérer son password par email
  • Possibilité de rester connecter avec un remember_me
  • Ajout d’information concernant le nombre de tickets filtrés ou vues
  • Possibilité pour chaque utilisateur loggé de suivre un ticket. Un utilisateur qui suit un ticket recevra ainsi à chaque mise à jour de ce ticket un email concernant cette modification.
  • Les utilisateurs ne peuvent plus changer leur email.

Enfin comme d’habitude voici mon fichier capistrano de déployement pour faciliter celui-ci.

Ficher de déployement capistrano

<typo:code lang=”ruby”> set :application, “oupsnow” set :repository, “git://github.com/shingara/oupsnow.git” set :domain, “dev.shingara.fr”

If you aren’t deploying to /u/apps/#{application} on the target

servers (which is the default), you can specify the actual location

via the :deploy_to variable:

set :deploy_to, “XXXXXXXXX”

If you aren’t using Subversion to manage your source code, specify

your SCM below:

set :scm, :subversion

set :scm, :git set :git_enable_submodules, 1

set :runner, “xxxx” set :user, “xxxx” set :use_sudo, false

set :thin_conf, “/etc/thin/#{domain}.yml”

set :rails_env, “production”

role :app, domain role :web, domain role :db, domain, :primary => true

task :update_config, :roles => [:app] do run “ln -s #{shared_path}/config/database.yml #{release_path}/config/database.yml” run “ln -s #{shared_path}/config/email.yml #{release_path}/config/email.yml” run “ln -s #{shared_path}/config/initializers/errornot.rb #{release_path}/config/initializers/errornot.rb” run “cd #{release_path} && echo ‘GOOGLE_ANALYTICS="XXXXXXXX"’ >> config/environment.rb” end

namespace :deploy do task :start, :roles => [:app] do

run "thin -C #{thin_conf} start"

end

task :stop, :roles => [:app] do

run "thin -C #{thin_conf} stop"

end

task :restart, :roles => [:app] do

run "thin -C #{thin_conf} restart"

end end

task :update_db do run “cd #{current_path} && RAILS_ENV=#{rails_env} rake db:update” end

after “deploy:update_code”, :update_config after “deploy:symlink”, :update_db </typo:code>

English translation

Pourquoi Ruby et Ruby On Rails dans le développement d’application web ?

| Comments

Cette question a été posée dernièrement sur la Mailling List de RailsFrance. Effectivement, si on veut promouvoir Ruby dans le monde informatique français, il faut pouvoir argumenter pourquoi on trouve que c’est une bonne idée.

Tout le monde est en droit de se poser la question. Voici donc, pour moi, l’avantage de Ruby par rapport aux autres technologies à l’heure actuelle.

Ruby c’est fun

Matz, quand il a créé Ruby, a voulu faire un langage fun avec lequel il pourrait s’amuser à coder. Aujourd’hui tous les développeurs Ruby diront à peu près la même chose. Coder en Ruby est plaisant. L’avantage de ce point est qu’un développeur Ruby est plus détendu. Un développeur détendu est un développeur plus heureux. Un développeur plus heureux est motivant pour une équipe. Un développeur heureux essayera de faire son travail proprement. L’ambiance d’une équipe de développeur Ruby peut ainsi être agréable. Moins de stress sur un projet, c’est un projet qui part avec un peu plus de chances de réussir.

Ruby aime les tests

La communauté Ruby actuelle est convaincue de l’utilité des tests unitaires. Ainsi, chaque librairie est poussée par la communauté à avoir des tests. Beaucoup de développeurs, moi y compris, privilégierons une librairie avec des tests unitaires plutôt qu’une sans aucun tests.

Cette philosophie permet d’avoir un environnement de développement de test simplifié directement dans Rails. Pas besoin de se prendre la tête pour faire des tests. Si vous ne faites pas de tests de base : soit vous ne voulez pas en faire, ce que je ne recommande pas, soit vous le faites exprès.

Ruby aime le cloud

En ce moment, l’évolution logique du net est le Cloud Computing. L’idée du Cloud Computing est simple. Nos sites internet ne sont plus hébergés sur une seule machine. Les services sont séparés pour améliorer la scallabilité. Au sein de la communauté Ruby, les développeurs sont très attachés à cette idée. Ainsi beaucoup d’utilitaires pour gérer et utiliser son cloud commencent à voir le jour comme Chef. L’architecture même de Rails permet de facilement sortir de Ruby On Rails pour ainsi utiliser son Cloud. ActiveRessource en est la preuve.

Mais coder dans un Cloud implique de coder plusieurs briques. Le Ruby a des bindings pour tous ces utilitaires, comme les systèmes de queues ou les bases de Données Non-Relationnelle. Je ne dis pas que les autres ne peuvent pas le faire. Mais là encore c’est un effet de groupe. Chaque développeur ruby a envie de jouer avec un Cloud. On pense de plus en plus en cloud.

Les plugins de Rails

Ruby On Rails possède une très grande quantité de plugins. On peut ainsi facilement trouver la petite brique que l’on cherche pour sa propre utilisation. C’est plus que l’utilisation d’un module Drupal. Car là nous sommes dans un environement facilement modifiable et sans aucune limitation. Chose que Drupal peut vite avoir.

Les Ressources

Le plus grand reproche que l’on fait actuellement au choix de Ruby On Rails, c’est le manque de ressources. Effectivement, les ressources de développeurs Ruby sont plus faibles que pour d’autres langages. Mais ceci est selon moi un faux problème. L’apprentissage de Ruby et Ruby On Rails est assez simple si on connait la logique Objet. Ainsi, n’importe quel développeur Java peut tout à fait se mettre à Ruby et Ruby On Rails. Donc avec un expert Ruby/Rails, on peut former facilement une équipe complète et compétente.

Cet argumentaire n’engage bien sûr que moi et peut donc être sujet à caution.

Que cherche un développeur dans une offre d’emploi ?

| Comments

On m’a posé dernièrement cette question. Ça peut sembler bête au premier abord, mais après quelques secondes de réflexion on se rappelle que toutes les offres d’emplois sont pleines d’interrogation.

Donc qu’est ce que j’attends dans une offre d’emploi ?

  • Le nom de l’entreprise :

    Le nom de l’entreprise est toujours pratique ne serait-ce que pour zapper l’annonce si on aime pas cette entreprise. Ou alors rigoler encore plus en lisant l’offre d’emploi.

  • Le cœur de métier de l’entreprise :

    C’est toujours agréable de savoir si on va travailler pour une entreprise qui fait du beurre ou des sites Web. On peut ainsi éviter certains entretiens inutiles.

  • Le nombre de développeurs dans l’entreprise :

    C’est une question plutôt inhabituelle pour un recruteur, mais avoir cette information permet de savoir tout de suite si on sera le geek dans son coin qui sera interrompu pour faire de l’assistance Words alors qu’il n’a plus touché à un windows depuis 3 ans. Au contraire, si on voit qu’il y a une majorité de développeurs, on pourra se dire que ça sera la fête aux trolls. Un développeur aime les Trolls \o/.

  • Les personnes connues :

    Comme dans tous métiers, on connaît certaines personnes de réputation. Cela peut facilement aider un développeur à choisir cette offre d’emploi si une personne connue y est. En revanche, c’est aussi à double tranchant. Certains feront l’entretien juste pour voir cette personne. D’autres zapperont encore plus l’offre d’emploi à cause de cette même personne.

  • L’environnement de travail :

    L’OS utilisé en majorité par les développeurs de la société peut être un très bon indicateur parfois. Typiquement chez AF83 où je travaille encore en ce moment, tous les développeurs sont sous UNIX, soit GNU/Linux, soit MacOSX. Pour beaucoup, cela prouve la qualité des développeurs. Et là encore la guerre aux trolls pourra facilement être ouverte.

  • La contribution Open source possible et faite par l’entreprise :

    Avoir du temps pour faire de l’Open Source selon notre désir est un plus non négligeable selon moi. J’ai énormément de projets open source en cours que je fais en parallèle de mon emploi, mais si je pouvais les faire aussi durant une partie de celui-ci, je serais vraiment heureux. Ensuite le fait que la société produise du code Open Source, peut facilement permettre au développeur de jauger de la qualité du code de cette société. En effet, pourquoi est-ce toujours la société qui doit vérifier le code de ses futurs employés ?

Selon, moi ces 6 points ne sont hélas pas toujours renseignés dans une offre d’emploi et cela serait un plus non négligeable.

Sortie de Typo 5.4.0

| Comments

Ça y est, une nouvelle version de Typo est lancée dans la nature. Je n’ai hélas que très peu participé à cette nouvelle version faute de motivation/temps. Mais je suis toujours très content de voir une nouvelle version de ce blog sortir.

A chaque release, une nouvelle admin fait son apparition, mais à chaque fois elle est meilleure que la précédente, donc c’est une excellente chose.

J’ai bien-sûr mis à jour ce blog et j’ai aussi switché sur le nouveau thème par défaut. Je suis toujours aussi nul en design.

En petit cadeau, voici mon fichier capistrano que j’utilise pour déployer ce blog. Ça peux toujours vous servir. On ne sait jamais.

set :application, “typo” set :repository, “git://github.com/fdv/typo.git” set :domain, “blog.shingara.fr” # If you aren’t deploying to /u/apps/#{application} on the target # # servers (which is the default), you can specify the actual location # # via the :deploy_to variable: set :deploy_to, “/var/rails/blog-typo” # # # If you aren’t using Subversion to manage your source code, specify # # your SCM below: set :scm, :git set :runner, “rails” set :user, “rails” set :use_sudo, false set :thin_conf, “/etc/thin/#{domain}.yml” role :app, domain role :web, domain role :db, domain, :primary => true task :update_config, :roles => [:app] do run “cp -Rf #{shared_path}/config/* #{release_path}/config/” run “ln -s #{shared_path}/files #{release_path}/public/files” end task :update_gems, :roles => [:app] do run “cd #{release_path} && RAILS_ENV=production rake gems:install” end after “deploy:update_code”, :update_config after “deploy:update_code”, :update_gems namespace :deploy do task :start, :roles => [:app] do run “thin -C #{thin_conf} start” end task :stop, :roles => [:app] do run “thin -C #{thin_conf} stop” end task :restart, :roles => [:app] do run “thin -C #{thin_conf} restart” end end task :clear_cache, :roles => [:app] do run “cd #{current_path} && RAILS_ENV=production rake sweep_cache” run “cd #{current_path} && RAILS_ENV=production rake tmp:cache:clear” end after “deploy:restart”, :clear_cache after “deploy:start”, :clear_cache

English Translation

Sortie de Oupsnow 0.4.0

| Comments

Ca y est, Oupsnow 0.4.0 est enfin sorti. Cette version est un refactoring quasiment complet. Après avoir eu une version 0.3.0 en Merb/DataMapper, cette version est désormais en Rails/MongoDB. Le back-end et le serveur ont changé.

Cette nouvelle version, outre son refactoring comprend aussi l’ajout de quelques nouvelles fonctionnalités.

  • Ajout d’un filtre par Status dans la recherche de ticket
  • Ajout de la possibilité de changer la fonction de tous les membres d’un project
  • Ajout de la preview des tickets et commentaires sur les tickets
  • Ajout de la visualisation de la milestone courante dans la visualisation d’un ticket
  • Possibilité d’ordonner tous les champs de recherche dans la vue des tickets
  • Login par l’email et plus par le pseudo

Vous pouvez télécharger cette version sur rubyforge

Si vous souhaitez tester cette version, une version de demo de oupsnow est en ligne. Les login/mdp sont : admin@admin.com/oupsnow. Amusez vous bien.

Comment tester devise ? réélement ?

| Comments

Alors que j’ai cherché comment tester facilement Devise. J’ai indiqué une technique dans mon précédent post. Mais cette technique est loin d’être la meilleure. Voici donc la nouvelle solution, la solution officielle.

Il suffit d’inclure Devise::TestHelpers. Ensuite pour se logger avec un utilisateur, on utilise la méthode sign_in. La méthode sign_out existe aussi.

Devise ? c’est bien, mais il faut le tester.

| Comments

Alors que j’ai évoqué ma migration de Merb à Rails pour Oupsnow, il a fallu trouver un système d’authentification ORM Agnostique.

Le plugin d’authentification le plus connu à l’heure actuel est Authlogic. Ce plugin est vraiment très performant, mais tous les essais de le rendre ORM Agnostique ont été vain. C’est alors qu’au même moment, durant le Rails Summit 2009, George Guimarães et Carlos Antonio annoncent la sortie de Devise, un plugin Rails au dessus de Warden ( Rack middleware d’authentification). C’est exactement, ce qu’il me faut, un nouveau système d’authentification a tester et peut-être une possibilité d’ajouter une couche d’ORM Agnostique dedans. En plus Warden étant un RackMiddleware, je pourrais un peu tester ce que ça donne.

J’installe donc Devise et commence à l’utiliser dans Oupsnow. Tout se passe à merveille, jusqu’au moment où il faut faire les tests. Tout de suite le bât blesse. Les tests controlleurs de Rails ne communiquent pas avec la couche Rack qui n’est pas initialisée. On se retrouve donc avec une impossibilité de définir si un utilisateur est loggé ou non et si oui, qui est cet utilisateur.

Après de nombreux tests et essais. J’ai fini par trouver comment faire. Warden ajoute à la requête une variable d’environment dans la requête. On peux y accéder par request.env['warden']. Il suffit donc de remplir cette variable.

Pour avoir un utilisateur non loggé, il faut faire :

def unlogged request.env[‘warden’] = Warden::Proxy.new(request.env, {:default_strategies => [:rememberable, :authenticable],:silence_missing_strategies => true}) end

Pour se logger avec un utilisateur en particulier il faut faire :

def logged_as(user) proxy = Warden::Proxy.new(request.env, {:default_strategies => [:rememberable, :authenticable], :silence_missing_strategies => true}) proxy.set_user(user, :store => true, :scope => :user) request.env[‘warden’] = proxy end

Personnellement, j’aime beaucoup devise. A tel point que j’ai permis de le rendre ORM Agnostique et compatible avec MongoMapper.

EDIT du 30 Novembre 2009: la technique indiquée ici n’est pas optimum et ne marche pas avec les dernières versions de Devise. utilisez plutôt la technique décrite dans mon ticket Comment tester devise ? réélement ?