Dans ce fichier nous allons voir comment lancer des programmes en serveur via Ruby et Rails, et comment les programmer pour qu'ils tournent régulièrement.
Pour que cela marche, il faut :
- Avoir Rails d'installé, un compte Heroku branché. Tout est marqué ici
- S'y connaître un petit peu en Ruby
Nous allons voir comment brancher un job via Rails et Heroku. Tout d'abord il faut créer une app rails
$ rails new jobs-test
Ensuite remplacer le Gemfile par un Gemfile qui marche. Puis faire ses premiers push :
$ bundle install
$ git add .
$ git commit -m "first commit"
$ heroku create nom_du_mon_app_trop_cool
$ git push heroku master
Voilà, nous avons une version en ligne de notre application vide. Maintenant, nous allons dire à Heroku que nous voulons utiliser la fonctionnalité du Scheduler, qui permet de programmer des "tasks" à intervalles régulières :
$ heroku addons:create scheduler:standard
Maintenant que nous avons branché Heroku pour qu'il soit possible de créer des tâche. Puis nous verrons comment dire à Heroku d'exécuter ces tâches. Les tâches sont dans le dossier lib/tasks
. La façon la plus simple de générer des tasks est de rentrer la ligne de commande suivante :
$ rails generate task nom_de_ma_task
Ainsi, un fichier lib/tasks/nom_de_ma_task.rake
va être créé. Dans ce fichier, remplacer le contenu par :
desc "Petite description de ma task !"
task nom_de_ma_task: :environment do
# ici mettre le code que l'on veut run
end
En exécutant $ rake --tasks
, on pourra voir dans la liste que ma task en mentionnée, et que l'on peut l'exécuter en faisant $ rake nom_de_ma_task
.
Une fois l'app, sur Heroku, on peut exécuter la task en faisant :
$ heroku run rake nom_de_ma_task
Plutôt cool, mais ce n'est pas exactement ce que l'on voulait. Il faut aller dans My Apps, sélectionner l'app qui nous intéresse, puis dans l'onglet Overview, dans la partie Installed add-ons, cliquer sur Heroku Scheduler.
Puis l'interface est assez explicite pour ajouter un nouveau job ;)
Bon c'est cool tout ça, mais comment faire pour accéder à l'output de mes tasks, si par exemple ma task est un scrappeur ? Il existe une multitude de solutions (s'envoyer des emails, enregistrer dans un spreadsheet), mais nous allons voir deux solutions qui merchent bien
En faisant la commande suivante :
$ heroku logs --ps scheduler
Il est possible de voir tous les logs de notre application. Heroku reporte notamment toutes les lignes du genre : puts "Bonjour ceci est une ligne
. Donc pour avoir le report de ce qui nous intéresse, il suffit de faire :
puts "Début de mon programme"
# Tout le programme tourne ici
puts "Le programme a bien tourné, voici la data qui m'intéresse :"
puts nom_de_la_variable_qui_contient_toutes_les_donnees
Si l'on créé un model IScrappedThat
, avec comme attributs les datas qui nous intéressent, il est possible de créer à chaque appel de notre task une instance de notre IScrappedThat. Puis il suffit de faire une view index qui a comme contenu :
def index
@mymodels = Mymodel.all
render json: @mymodels
end
Et à partir de là, je peux accéder à mon programme. En ligne via http://www.nom-de-mon-app.herokuapp.com/mymodels.
C'est mieux de mettre tout le code des tasks dans des services
Au cas où il y ait plusieurs tasks qui appartiennent à la même catégorie (ex: Newsletter), il est mieux de les regrouper. Ainsi, on fera un commun aux tasks.
$ rails generate task nom_de_ma_categorie nom_de_ma_task
Ce qui va créer un fichier lib/tasks/nom_de_ma_category.rake
. Dedans il suffit d'y rentrer les lignes suivantes :
namespace :nom_de_ma_categorie do
desc "Ma super task 1 !!"
task nom_de_ma_task: :environment do
# vends-moi du rêve ici
end
desc "Ma super task 2 !!"
task nom_de_ma_task_numero_2: :environment do
# vends-moi du rêve ici, volume 2
end
end
Pour appeler mes tasks, il suffit de faire $ rake nom_de_ma_categorie:nom_de_ma_task
.
Easy, il suffit de mettre dans notre task une connerie du genre :
desc "Petite description de ma task !"
task nom_de_ma_task: :environment do
if it_is_monday
# fais la task
else
# ne fais rien
end
end
Les temps de serveur coûtent cher, donc passer par Heroku pour ça est fortement déconseillé à cause du prix. Deux solutions :
- Faire tourner le programme sur un Rasberry Pi
- Utiliser un serveur privé
- La doc de Heroku explique très bien comment faire des jobs
- Les Ruby Snack correspondants montrent comment brancher ses rake : Ruby Snack #63, Ruby Snack #68,