Skip to content

Instantly share code, notes, and snippets.

@MrCoffey
Last active January 23, 2021 04:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MrCoffey/789032e8580407ee35c1 to your computer and use it in GitHub Desktop.
Save MrCoffey/789032e8580407ee35c1 to your computer and use it in GitHub Desktop.
Usando whenever con rake

CREANDO TAREAS CON WHENEVER Y RAKE

Es posible que en algún momento lleguemos a necesitar que alguna tarea deba ser ejecutada cada cierto tiempo en estos trabajos se conocen como cronjobs.

En este breve ejemplo exploramos como implementarlos en una applicación de Ruby On Rails, por ejemplo en uno de nuestros tutoriales explicábamos como enviar correos a todos nuestros usuarios con la ayuda de rake, si bien podemos ejecutarla nosotros mismos, sería mucho mejor si alguien hiciera ese trabajo por nosotros. Bueno para esto existe Whenever una gema que nos permite programar tareas haciendo uso de cron log.

La cuestión es que cron, luce así:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
01  * * * * root nice -n 19 run-parts /etc/cron.hourly
50  0 * * * root nice -n 19 run-parts /etc/cron.daily
22 4 * * 0 root nice -n 19 run-parts /etc/cron.weekly
42 4 1 * * root nice -n 19 run-parts /etc/cron.monthly

Sip, no se ve tan divertido, así que comencemos a configurar whenever.

1) Agregamos Whenever a nuestro proyecto

gem install whenever

# En tu script

require 'whenever'

# Ó en ruby on rails

gem "whenever", :require => false

# Luego

bundle install

Una vez tenemos instalado whenever nos basta con ir a la raíz de nuestra aplicación y correr el siguiente comando el cual creara un archivo llamado schedule.rb dentro de nuestra carpeta config.

wheneverize .

2) Crear la tarea de rake

namespace :newsletter do
  desc "Send a daily newsletter to all suscribed users"
  task :daily => :environment do
    users = User.all
    users.for_each do |user|
      user.Newsletter.daily(user).deliver
    end
    puts "#{Time.now} - Deliver success!"
  end
end

Si quieres saber más sobre las tareas de rake puedes ver nuestro vídeo introductorio siguiendo este link.

Para correr esta tarea de rake basta con usar el comando:

rake newsletter:daily

Ahora, ya que tenemos la tarea que vamos a programar procedemos a abrir nuestro archivo schedule.rb en el cual luce así.

# Use this file to easily define all of your cron jobs.
#
# It's helpful, but not entirely necessary to understand cron before proceeding.
# http://en.wikipedia.org/wiki/Cron

# Example:
#
# set :output, "/path/to/my/cron_log.log"
#
# every 2.hours do
#   command "/usr/bin/some_great_command"
#   runner "MyModel.some_method"
#   rake "some:great:rake:task"
# end
#
# every 4.days do
#   runner "AnotherModel.prune_old_records"
# end

# Learn more: http://github.com/javan/whenever

Whenever hace uso de una sintaxis mucho más idiomática, lo cual hace más fácil su lectura every [x].[minute/hour/day/week/etc.], :at => [time] do

Procedemos a escribir nuestra rutina para que todos los días a las 10 de la mañana envié nuestro newsletter diario (no hagan esto a menos que quieran echar a sus usuarios), también configure un espacio en mi aplicación para guardar los logs de whenever para así tener un feedback de que se está ejecutando como debería.

set :output, {:error => "log/cron_error_log.log", :standard => "log/cron_log.log"}

every 1.day, :at => '10:00 am' do
  rake "newsletter:daily"
end

3.) Actualizando el crontab

Ahora ya que configuramos nuestras tareas tanto con rake como con whenever es necesario actualizar las rutinas que queremos que whenever ejecute por nosotros

whenever --update-crontab

Esto nos devolverá el siguiente mensaje

[write] crontab file updated

Con esto debería ser suficiente para que nuestra nueva tarea funcione correctamente, una cosa importante es que probablemente no queremos esperar hasta el otro día para ver si la rutina realmente funciona, lo que podemos hacer en este caso es programarla para que se ejecute cada minuto y de esta forma verificar por medio de los logs si en realidad esta todo correctamente configurado, la tarea puede ser algo tan fácil como que imprimir un "hola mundo", adicionalmente si quieres verificar la rutina puedes revisarla con el comando crontab -l esto debería devolver algo muy parecido a esto.

0 22 * * * /bin/bash -l -c 'cd /Users/coffey/rails_apps/mailer_test && RAILS_ENV=development bundle exec rake events:fetch --silent >> log/cron_log.log 2>> log/cron_error_log.log'

Ejemplos de rutinas (puedes encontrar más ejemplos en el README de whenever)

every 3.hours do
  runner "MyModel.some_process"
  rake "my:rake:task"
  command "/usr/bin/my_great_command"
end

every 1.day, :at => '4:30 am' do
  runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
end

every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
  runner "SomeModel.ladeeda"
end

every :sunday, :at => '12pm' do # Use any day of the week or :weekend, :weekday
  runner "Task.do_something_great"
end

# run this task only on servers with the :app role in Capistrano
# see Capistrano roles section below
every :day, :at => '12:20am', :roles => [:app] do
  rake "app_server:task"
end

Esto es todo por ahora, si tienen comentarios o encuentrán algún error pueden comentar y revisaré tan pronto como me sea posible :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment