Elle ne plante pas. Elle ne s'imprime nulle part. Elle reste.It doesn't crash. It logs nowhere. It stays.
Au numéro précédent, le WaitGroup nous rendait la main quand toutes les goroutines avaient fini. Mais que se passe-t-il pour celle qui ne finit jamais ? Une goroutine bloquée sur un envoi que plus personne ne lira ne lève aucune erreur, n'apparaît dans aucun log, et ne décrémente aucun compteur. Elle reste là, vivante et inutile, jusqu'à l'arrêt du process — en retenant au passage tout ce qu'elle référence. C'est la fuite la plus silencieuse de Go.Last issue, the WaitGroup handed control back once every goroutine had finished. But what about the one that never finishes? A goroutine blocked on a send nobody will ever read raises no error, shows up in no log, decrements no counter. It just lingers, alive and useless, until the process dies — holding on to everything it references along the way. It's Go's quietest leak.
func first(urls []string) string { ch := make(chan string) // non bufferisé for _, u := range urls { go func(u string) { ch <- fetch(u) // bloque jusqu'à ce qu'on LISE }(u) } return <-ch // on prend la 1re réponse… et on part } // les autres : bloquées sur l'envoi, à jamais
Une fuite n'est pas un crash : c'est un déséquilibre. Tu lances trois goroutines, tu en rejoins une, et les deux autres ne reviennent jamais. Le compte ne tombe pas à zéro — il s'arrête à deux, pour toute la durée du programme.A leak isn't a crash: it's an imbalance. You launch three goroutines, rejoin one, and the other two never come back. The count doesn't fall to zero — it stalls at two, for the life of the program.
« Toute goroutine doit avoir une sortie garantie. » Le go est facile à écrire ; le retour, lui, n'est promis par personne. Tout ce numéro consiste à voir une goroutine qui ne reviendra pas, à la mesurer, puis à lui donner la porte qui lui manque."Every goroutine must have a guaranteed exit." The go is easy to write; the return is promised by no one. This whole issue is about spotting a goroutine that won't come back, measuring it, then handing it the door it's missing.
Le runtime ne considère pas une goroutine bloquée comme une erreur : attendre sur un channel est un état parfaitement légal. Il n'y a erreur fatale (fatal error, pas un panic rattrapable) que si TOUTES les goroutines sont bloquées en même temps (« all goroutines are asleep — deadlock! »). Tant qu'une seule tourne — souvent main — les fuites restent invisibles, et s'accumulent.The runtime doesn't treat a blocked goroutine as an error: waiting on a channel is a perfectly legal state. It only dies with a fatal error (not a recoverable panic) if ALL goroutines are blocked at once ('all goroutines are asleep — deadlock!'). As long as one keeps running — usually main — the leaks stay invisible, and pile up.