ruby-on-rails heroku scheduled-tasks

ruby on rails - ¿Cómo puedo programar un trabajo ''semanal'' en Heroku?



heroku panel (5)

Como se discutió aquí , y usando la lógica anterior de Rob, aquí están los scripts bash desglosados ​​por un día de la semana, una vez al mes y en una fecha específica.

Ejecuta una tarea todos los lunes:

if [ "$(date +%u)" = 1 ]; then MY_COMMAND; fi

Ejecuta una tarea cada 1er día en un mes:

if [ "$(date +%d)" = 01 ]; then MY_COMMAND; fi

También puede ejecutar un trabajo todos los años el 24 de diciembre:

if [ "$(date +%m)" = 12 ] && [ "$(date +%d)" = 24 ]; then MY_COMMAND; fi

Tengo una aplicación Rails implementada en Heroku con el complemento del programador Heroku funcionando con éxito para trabajos diarios.

Ahora quiero un trabajo semanal , pero el complemento del programador no me permite una opción semanal.

Alguna sugerencia sobre cómo podría lograr esto:

  • Intenté usar rufus-scheduler en el pasado pero me causó algunos problemas, así que no es una opción. Mira here para más detalles.
  • Estoy pensando en algo parecido a verificar el día actual dentro de un trabajo diario. ¿Alguien lo ha probado y tiene comentarios o sabe de problemas con el enfoque?
  • Otras ideas muy apreciadas.

No es ideal, pero me he tomado la tarea de agregar una variable de entorno RUN_IF para rake tareas ejecutadas a través de heroku: planificador que me permite programar horarios semanales y mensuales para trabajos.

# lib/tasks/scheduler.rake def run? eval ENV.fetch(''RUN_IF'', ''true'') end def scheduled if run? yield else puts "RUN_IF #{ENV[''RUN_IF''].inspect} eval''d to false: aborting job." end end # lib/tasks/job.rake task :job do scheduled do # ... end end

Si se ejecuta una tarea de rake sin una variable RUN_IF, se ejecutará. De lo contrario, el trabajo se cancelará a menos que el valor de RUN_IF evalúe a un valor falsey.

$ rake job # => runs always $ rake job RUN_IF=''Date.today.monday?'' # => only runs on Mondays $ rake job RUN_IF=''Date.today.day == 1'' # => only runs on the 1st of the month $ rake job RUN_IF=''false'' # => never runs (not practical, just demonstration)

Similar a otras ideas anteriores, pero prefiero mover los detalles de programación fuera del código de la aplicación.


Si no quiere o no puede hacer esto con Rake, otra opción es hacer esto con Ruby de bash:

#!/bin/bash cmd="echo your schedule job here" # Only run on even days ruby -e ''if Time.now.utc.day.even?; puts "Not today!"; exit 1; end'' && $cmd "$@"

Esto funciona incluso para proyectos que no sean de rubí (como en mi caso: Clojure).


Un enfoque sería el de su segundo punto:

activar el complemento cron de Heroku y agregar una tarea cron.rake en la app/lib/tasks

Active el complemento del programador Heroku y agregue una tarea scheduler.rake en la app/lib/tasks

task :your_weekly_task=> :environment do if Time.now.friday? # previous answer: Date.today.wday == 5 #do something end end

Incluso puede darse el lujo de definir el día en que desea que se ejecute su tarea; o) (5 es para el viernes)

EDITAR: por cierto, Cron está en desuso y Heroku recomienda cambiar a su complemento Scheduler. Sin embargo, esto no cambia el enfoque para un trabajo semanal.

EDIT2: ajustes a mi respuesta basados ​​en los comentarios de sunkencity.


Una opción alternativa que usa solo código de shell. Configura el programador de Heroku por hora y haz una comparación con el comando de fecha:

# setting the schedular to run hourly at *:30 is equivalent to the # crondate: 30 8 * * 1 if [ "$(date +%H)" = 08 ] && [ "$(date +%d)" = 01 ]; then YOUR_COMMAND ; fi

He usado este código para imitar a cron en mi zona horaria local:

nz_hour="$(TZ=NZ date +%H)" ; nz_day="$(TZ=NZ date +%d)" ; if [ "$nz_hour" = 08 ] && [ "$nz_day" = 01 ]; then YOUR_COMMAND ; fi