ProgrammationDéveloppeur Go

Que faut-il savoir sur le travail avec time.Timer et time.Ticker en Go ? Quelles sont les différences clés, les particularités d'utilisation correcte et les erreurs courantes lors de leur arrêt/réinitialisation ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Le package time fournit deux outils utiles : Timer et Ticker.

  • Timer est utilisé pour un délai unique (il se déclenche une fois après un certain temps).
  • Ticker — pour des événements périodiques réguliers (intervalle).

Différences clés :

  • Timer après son déclenchement "s'éteint", il doit être réinitialisé (Reset) pour être utilisé à nouveau.
  • Ticker génère des événements tant qu'il n'est pas explicitement arrêté par la méthode Stop().

Particularités d'utilisation :

  • Appelez toujours Stop() sur Timer/Ticker lors de la fin de l'utilisation, pour éviter les fuites de ressources.
  • Après avoir appelé Stop() sur Timer, il peut être nécessaire de « vidanger » le canal : si le minuteur a été déclenché avant Stop(), la lecture du canal est obligatoire.

Exemple d'utilisation correcte de Timer :

t := time.NewTimer(2 * time.Second) defer t.Stop() // obligatoire! select { case <-t.C: fmt.Println("Le temps est écoulé !") case <-otherDone: if !t.Stop() { <-t.C // vidons le canal si nécessaire } }

Question piège

Peut-on réutiliser immédiatement Timer après avoir reçu une valeur du canal t.C ? Que se passe-t-il si on ne fait pas t.Stop() ?

Réponse : Le minuteur ne doit pas être réinitialisé immédiatement sans un appel à Stop() et la possible lecture du canal. Si on ne fait pas t.Stop(), il pourrait rester une goroutine "morte" ou un déclencheur inattendu au cycle suivant (le canal n'est pas vidé). Utilisation correcte : appelez Stop(), et si Stop() retourne false — assurez-vous de vider le canal en lisant depuis t.C.

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet


Histoire

Dans le service de notifications d'une startup, des minuteurs étaient utilisés pour réinitialiser les tentatives de livraison. Après leur déclenchement, ils étaient immédiatement réinitialisés sans être arrêtés — résultat : le flux de goroutines augmentait, le processus "fuyait", le système tombait à cause du manque de mémoire.

Histoire

Dans un grand projet e-commerce, pour des mises à jour périodiques de produits, un Ticker était utilisé, qui n'était pas arrêté lors de la fin du gestionnaire. Le gestionnaire "pendait" même après la suppression de l'utilisateur, continuant à consommer du CPU.

Histoire

Dans les tests, Stop() n'était pas appelé pour le minuteur — les tests échouaient de manière aléatoire parce que le canal du minuteur n'était pas libéré, attendant un deuxième "ping" du minuteur, qui n'arrivait jamais.