56 lines
1.4 KiB
Ruby
56 lines
1.4 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
# Una tarea que se corre periódicamente
|
||
|
class PeriodicJob < ApplicationJob
|
||
|
class RunAgainException < StandardError; end
|
||
|
|
||
|
STARTING_INTERVAL = Stat::INTERVALS.first
|
||
|
|
||
|
# Tener el sitio a mano
|
||
|
attr_reader :site
|
||
|
|
||
|
# Descartar y notificar si pasó algo más.
|
||
|
#
|
||
|
# XXX: En realidad deberíamos seguir reintentando?
|
||
|
discard_on(StandardError) do |_, error|
|
||
|
ExceptionNotifier.notify_exception(error)
|
||
|
end
|
||
|
|
||
|
# Correr indefinidamente una vez por hora.
|
||
|
#
|
||
|
# XXX: El orden importa, si el descarte viene después, nunca se va a
|
||
|
# reintentar.
|
||
|
retry_on(PeriodicJob::RunAgainException, wait: 1.try(STARTING_INTERVAL), attempts: Float::INFINITY, jitter: 0)
|
||
|
|
||
|
private
|
||
|
|
||
|
# Las clases que implementen esta tienen que usar este método al
|
||
|
# terminar.
|
||
|
def run_again!
|
||
|
raise PeriodicJob::RunAgainException, 'Reintentando'
|
||
|
end
|
||
|
|
||
|
# El intervalo de inicio
|
||
|
#
|
||
|
# @return [Symbol]
|
||
|
def starting_interval
|
||
|
STARTING_INTERVAL
|
||
|
end
|
||
|
|
||
|
# La última recolección de estadísticas o empezar desde el principio
|
||
|
# de los tiempos.
|
||
|
#
|
||
|
# @return [Stat]
|
||
|
def last_stat
|
||
|
@last_stat ||= site.stats.where(name: stat_name).last ||
|
||
|
site.stats.build(created_at: Time.new(1970, 1, 1))
|
||
|
end
|
||
|
|
||
|
# Devuelve el comienzo del intervalo
|
||
|
#
|
||
|
# @return [Time]
|
||
|
def beginning_of_interval
|
||
|
@beginning_of_interval ||= last_stat.created_at.try(:"beginning_of_#{starting_interval}")
|
||
|
end
|
||
|
end
|