rango minutos horas cada go

go - horas - crontab cada 60 minutos



¿Hay alguna manera de hacer tareas repetitivas a intervalos en Golang? (5)

¿Qué tal algo así como

package main import ( "fmt" "time" ) func schedule(what func(), delay time.Duration) chan bool { stop := make(chan bool) go func() { for { what() select { case <-time.After(delay): case <-stop: return } } }() return stop } func main() { ping := func() { fmt.Println("#") } stop := schedule(ping, 5*time.Millisecond) time.Sleep(25 * time.Millisecond) stop <- true time.Sleep(25 * time.Millisecond) fmt.Println("Done") }

Playground

¿Hay alguna forma de realizar tareas en segundo plano repetitivas en Go? Estoy pensando en algo como Timer.schedule(task, delay, period) en Java. Sé que puedo hacer esto con un goroutine y Time.sleep() , pero me gustaría algo que se detenga fácilmente.

Esto es lo que tengo, pero se ve feo para mí. ¿Hay una manera más limpia / mejor?

func oneWay() { var f func() var t *time.Timer f = func () { fmt.Println("doing stuff") t = time.AfterFunc(time.Duration(5) * time.Second, f) } t = time.AfterFunc(time.Duration(5) * time.Second, f) defer t.Stop() //simulate doing stuff time.Sleep(time.Minute) }


Consulte esta biblioteca: https://github.com/robfig/cron

Ejemplo como a continuación:

c := cron.New() c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") }) c.AddFunc("@hourly", func() { fmt.Println("Every hour") }) c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") }) c.Start()


La función time.NewTicker un canal que envía un mensaje periódico y proporciona una forma de detenerlo. Úselo algo como esto (no probado):

ticker := time.NewTicker(5 * time.Second) quit := make(chan struct{}) go func() { for { select { case <- ticker.C: // do stuff case <- quit: ticker.Stop() return } } }()

Puede detener al trabajador cerrando el canal de quit : close(quit) .


Si no le importa el cambio de tilde (dependiendo de cuánto tiempo tomó previamente en cada ejecución) y no desea usar canales, es posible utilizar la función de rango nativo.

es decir

package main import "fmt" import "time" func main() { go heartBeat() time.Sleep(time.Second * 5) } func heartBeat(){ for range time.Tick(time.Second *1){ fmt.Println("Foo") } }

Playground


Una respuesta más amplia a esta pregunta podría considerar el enfoque de Lego brick que a menudo se usa en Occam, y se ofrece a la comunidad Java a través de JCSP . Hay una muy buena presentación de Peter Welch sobre esta idea.

Este enfoque plug-and-play se traduce directamente en Go, porque Go usa los mismos fundamentos del proceso secuencial de comunicación que Occam.

Entonces, cuando se trata de diseñar tareas repetitivas, puede construir su sistema como una red de flujo de datos de componentes simples (como rutinas) que intercambian eventos (es decir, mensajes o señales) a través de canales.

Este enfoque es compositivo: cada grupo de componentes pequeños puede comportarse como un componente más grande, ad infinitum. Esto puede ser muy poderoso porque los complejos sistemas concurrentes están hechos de ladrillos fáciles de entender.

Nota al pie: en la presentación de Welch, utiliza la sintaxis de Occam para canales, ¡que es ! y ? y estos corresponden directamente a ch <- y <- ch en Go.