Schedule Queues

Reloj con varios indicadores en verde encendiéndose cada N minutos (múltiples disparos en una hora).

Tabla de contenidos


Problema

Cuando usamos Vapor Queues para planificar trabajos, la API típica es:

app.queues
    .schedule(MyJob()).hourly().at(0)

Esto planifica cada hora. Si queremos ejecutarlo cada N minutos (p. ej., cada 5, 10 o 15), tenemos que registrar manualmente varios .at(…), lo que acaba en código repetitivo, propenso a errores (minutos duplicados/olvidados) y poco legible.


Solución

Extraemos un helper sobre Application.Queues que registra el mismo ScheduledJob múltiples veces dentro de la hora usando un stride con paso minutes. Así, con una sola llamada expresamos: “ejecútalo cada N minutos”.

extension Application.Queues {
    func scheduleEvery(
        _ job: ScheduledJob, 
        minutes: Int
    ) {
        for minuteOffset in stride(
            from: 0, 
            to: 60, 
            by: minutes
        ) {
            schedule(job).hourly()
                .at(.init(integerLiteral: minuteOffset))
        }
    }
}

Puntos clave:

  • Usa stride(from: 0, to: 60, by: minutes) para generar los offsets de minuto dentro de la hora.
  • Por cada offset se registra hourly().at(…), evitando duplicar lógica.
  • Si minutes no divide 60, la última ejecución será el mayor múltiplo < 60 (p. ej., minutes = 7 ⇒ 0, 7, 14, …, 56).

Resultado

Ejemplo de uso:

func configure(_ app: Application) throws {
    app.queues.scheduleEvery(MyJob(), minutes: 5)
}

Una API concisa y autoexpresiva para tareas periódicas cortas:

  • Menos boilerplate: una sola llamada registra todos los disparos.
  • Menos errores: sin listas manuales de .at(…) ni minutos duplicados.
  • Legible y testeable: el patrón es evidente y fácil de verificar.

Keep coding, keep running 🏃‍♂️