El paquete time proporciona dos herramientas útiles: Timer y Ticker.
Diferencias clave:
Timer después de activarse "se apaga", debe ser reiniciado (Reset) para usarlo de nuevo.Ticker genera eventos hasta que se detiene explícitamente con el método Stop().Características de uso:
Stop() en Timer/Ticker al finalizar el trabajo para evitar fugas de recursos.Stop() en Timer, puede ser necesario "drain" el canal: si el temporizador se activó antes de Stop(), la lectura del canal es obligatoria.Ejemplo de uso correcto de Timer:
t := time.NewTimer(2 * time.Second) defer t.Stop() // ¡obligatorio! select { case <-t.C: fmt.Println("¡Se acabó el tiempo!") case <-otherDone: if !t.Stop() { <-t.C // drenamos el canal si es necesario } }
¿Se puede reutilizar de inmediato un Timer después de recibir un valor del canal t.C? ¿Qué sucederá si no se hace t.Stop()?
Respuesta: El temporizador no debe restablecerse inmediatamente sin llamar a Stop() y posiblemente leer del canal. Si no se hace t.Stop(), puede quedar una gorutina "muerta" o un disparador inesperado en el siguiente ciclo (el canal no se ha limpiado). Uso correcto: llame a Stop(), y si Stop() devuelve falso, asegúrese de drenar el canal leyendo de t.C.
Historia
Historia
Ticker, que no se detenía al finalizar el manejador. El manejador "colgaba" incluso después de eliminar un usuario, continuando consumiendo CPU.Historia
En las pruebas, no se llamaba a Stop() para el temporizador; las pruebas se colgaban aleatoriamente porque el canal del temporizador no se liberaba, se esperaba un segundo "ping" del temporizador, que nunca llegaba.