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