Whenever: Una gema en Ruby para facilitar la escritura de nuestros ficheros de cron


Trying BrewDog’s ‘IPA Is Dead’ range of single-hopped IPAs Whenever es una gema en Ruby que he probando para ponerla en un proyecto en el que estoy actualmente y merece la pena comentarla. Normalmente cuando he tenido que escribir algún cron para que en ciertos momentos se ejecuten automáticamente tareas que necesita un proyecto de su apoyo, siempre se presentan las dudas de cómo es el formato, horas minutos y qué orden llevan, bueno eso es normal, no estoy haciendo cron constantemente. Pero a lo que voy, es que Whenever nos facilita esta labor desde un lenguaje natural de escritura de nuestros cron. El aspecto que tiene un cron es algo parecido al que te muestro:

PATH=/usr/local/bin:/usr/bin:/bin
RAILS_ENV=production
MAILTO=notificacion@micorreo.com
RAKE=bundle exec rake

# m h dom mon dow user command

30 7 * * * root cd $HOME/app; $RAKE login:clean_expired > /dev/null

22 2 * * * root cd $HOME/app; $RAKE db:import > /dev/null

35 5 * * * root find $HOME/app/public/system -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf \{\} \; > /dev/null

Bueno, pues ahora la gema de Ruby Whenever, nos facilita esta labor de acordarnos y de escribir este tipo de formato tradicional de cron, por ejemplo, si quiero ejecutar mi tarea todos los días a las 4:40, pues únicamente ponemos

every :day, :at => ‘4:40 am’ do
         rake “users:reset_password”
end

Es mucho más natural y sencillo verdad? pues sigamos.

¿Cómo puedo instalarla en mi proyecto? 

Lo podemos hacer desde la línea de comando con:

# gem install whenever

o lo puedes también incorporar al Gemfile:

gem ‘whenever’, :require => false

Piensa que también será necesario incluir en nuestro fichero de deploy.rb de Capistrano, teniendo en cuenta el orden de dónde las colocas estas líneas, ya que nos puede arrojar errores de que no ejecuta el bundle en primer lugar, las siguientes líneas:

set :whenever_command, “bundle exec whenever”
require “whenever/capistrano”

Una vez que ya tenemos esta parte hecha, ahora ya ponemos ejecutar el inicio de whenever, para comenzar y que ponga nuestro fichero de schedule.rb en marcha (de forma automática al ejecutar comando, no tenemos que crearlo) que será donde podremos escribir nuestras tareas. El comando que debemos ejecutar es:

# wheneverize .

Con esto, ya tenemos puesto en marcha todo lo necesario para comenzar a escribir nuestro primer cron con whenever. Para eso editamos nuestro schedule.rb y escribimos las tareas que necesitemos, por ejemplo:

env : PATH, ‘/usr/local/bin:/usr/bin:/bin’

Si queremos incorporar que nuestra salida la llevemos a un destino, en este caso a /dev/null

set : output, {:standard => nil}

Para enviar notificaciones en caso de error en el cron por email ponemos:

env :MAILTO, ‘notificacion@miemail.com’

Y ahora las tareas cada día a las 23:17 me ejecutas un bundle exec rake login:clean_expired

every :day, :at => ’23:17 pm’ do
rake “login:clean_expired”
end

Si ahora queremos ejecutar un comando linux find lo hacemos así:

every :day, :at => ‘3:35 am’ do

command ‘find $HOME/app/public/ -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf \{\} \;’ NOTA IMPORTANTE: si necesitas ejecutar un comando que necesite un scape de \ como -exec rm -rf \{\} pon comillas simples en la ejecución del comando: command ‘find $HOME/app/public/ -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf \{\} \;’ si las ponemos con comillas dobles en la ejecución o traducción nos saldrá sin las \ y tendremos un error de ejecución.
end

Si necesitamos ejecutar una tarea a unas horas determinadas, con [] y las horas que necesitamos, lo tenemos listo

every :day, at: [7,15,18,20] do
rake “remind_pending_task”
end

Estos son algunos otros ejemplos que dispone la gema para otro tipo de tareas

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

every ‘0 0 27-31 * *’ do
command “echo ‘you can use raw cron syntax too'”
end

Pues realmente es sencillo una vez se tiene claro todas estas cosas, pero aún nos queda la pregunta ¿cómo se hace la traducción de nuestro schedule.rb a nuestro cron? la respuesta está en que si lo estamos probando en local lo hacemos con el comando:

# bundle exec whenever –update-crontab

que está situado en nuestro usuario y directorio /var/spool/cron/crontabs/

Si lo que queremos es ver que resultado nos proporciona como cron sin actualizar como el comando anterior:

# bundle exec whenever  

y vamos comprobando los resultados obtenidos.  Una vez que ya tenemos hechas nuestras comprobaciones, hacemos el deploy correspondiente y comentamos nuestro cron actual de script/deploy/integration/crontab para ver que no se nos dupliquen cuando hagamos dicha subida. Si todo lo tenemos correcto pues ya hacemos nuestro deploy a producción.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s