Saltar al contenido

Golang: Implementar un cron / ejecutar tareas en un momento específico

Puede que se de el caso de que halles algún error con tu código o trabajo, recuerda probar siempre en un ambiente de testing antes subir el código al trabajo final.

Solución:

Esta es una implementación general, que le permite configurar:

  • período de intervalo
  • hora de marcar
  • minuto para marcar
  • segundo en marcar

ACTUALIZADO: (la fuga de memoria fue reparada)

import (
"fmt"
"time"
)

const INTERVAL_PERIOD time.Duration = 24 * time.Hour

const HOUR_TO_TICK int = 23
const MINUTE_TO_TICK int = 00
const SECOND_TO_TICK int = 03

type jobTicker struct 
    timer *time.Timer


func runningRoutine() 
    jobTicker := &jobTicker
    jobTicker.updateTimer()
    for 
        <-jobTicker.timer.C
        fmt.Println(time.Now(), "- just ticked")
        jobTicker.updateTimer()
    


func (t *jobTicker) updateTimer() 
    nextTick := time.Date(time.Now().Year(), time.Now().Month(), 
    time.Now().Day(), HOUR_TO_TICK, MINUTE_TO_TICK, SECOND_TO_TICK, 0, time.Local)
    if !nextTick.After(time.Now()) 
        nextTick = nextTick.Add(INTERVAL_PERIOD)
    
    fmt.Println(nextTick, "- next tick")
    diff := nextTick.Sub(time.Now())
    if t.timer == nil 
        t.timer = time.NewTimer(diff)
     else 
        t.timer.Reset(diff)
    

la respuesta proporcionada por @Daniele B no es lo suficientemente buena, como dice @Caleb, esa implementación pierde memoria, porque cada vez que creamos un nuevo ticker, el anterior nunca se publicará.

así que envuelvo el time.timery reinícielo cada vez, un ejemplo aquí:

package main

import (
    "fmt"
    "time"
)

const INTERVAL_PERIOD time.Duration = 24 * time.Hour

const HOUR_TO_TICK int = 23
const MINUTE_TO_TICK int = 21
const SECOND_TO_TICK int = 03

type jobTicker struct 
    t *time.Timer


func getNextTickDuration() time.Duration 
    now := time.Now()
    nextTick := time.Date(now.Year(), now.Month(), now.Day(), HOUR_TO_TICK, MINUTE_TO_TICK, SECOND_TO_TICK, 0, time.Local)
    if nextTick.Before(now) 
        nextTick = nextTick.Add(INTERVAL_PERIOD)
    
    return nextTick.Sub(time.Now())


func NewJobTicker() jobTicker 
    fmt.Println("new tick here")
    return jobTickertime.NewTimer(getNextTickDuration())


func (jt jobTicker) updateJobTicker() 
    fmt.Println("next tick here")
    jt.t.Reset(getNextTickDuration())


func main() 
    jt := NewJobTicker()
    for 
        <-jt.t.C
        fmt.Println(time.Now(), "- just ticked")
        jt.updateJobTicker()
    

En caso de que alguien caiga en esta pregunta en busca de una solución rápida. Encontré una biblioteca ordenada que hace que sea muy fácil programar trabajos.

Enlace: https://github.com/jasonlvhit/gocron

La API es bastante sencilla:

import (
    "fmt"
    "github.com/jasonlvhit/gocron"
)

func task() 
    fmt.Println("Task is being performed.")


func main() 
    s := gocron.NewScheduler()
    s.Every(2).Hours().Do(task)
    <- s.Start()

Sección de Reseñas y Valoraciones

Al final de todo puedes encontrar las notas de otros desarrolladores, tú además tienes la libertad de mostrar el tuyo si lo deseas.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 4)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *