select est un puissant constructeur Go pour travailler avec des canaux. Il permet d'attendre la réception de données en provenance de plusieurs canaux ou leur fermeture. Dès qu'un des cas est prêt, la branche correspondante s'exécute, les autres sont ignorés lors de l'itération actuelle.
ch1 := make(chan int) ch2 := make(chan string) go func() { ch1 <- 42 }() go func() { ch2 <- "hello" }() select { case i := <-ch1: fmt.Println("reçu de ch1:", i) case s := <-ch2: fmt.Println("reçu de ch2:", s) default: fmt.Println("pas de communication") }
Nuances :
Que se passera-t-il si aucun canal n'est prêt à la lecture/écriture dans select et qu'il n'y a pas de bloc default ?
Réponse : Select sera bloqué jusqu'à ce qu'un des canaux soit prêt pour l'opération.
Histoire
Un développeur a implémenté une fonction d'interruption de flux de données via select sans bloc default, en supposant que la fonction "relâcherait le contrôle" après plusieurs tentatives. Les canaux sont restés vides et la fonction s'est bloquée indéfiniment dans select, provoquant le gel des flux de données du microservice.
Histoire
Utilisation de select avec plusieurs canaux, des panique se produisaient dans certaines goroutine lors de la fermeture de canaux non gérés dans select, ce qui entraînait des fuites et des plantages. Il n'y avait pas de vérification de la fermeture du canal (via la variable ok).
Histoire
Dans l'un des projets, les développeurs ont ajouté un bloc default dans select pour éviter les blocages. Mais cela a conduit à une boucle occupée - select s'exécutait dans une boucle, le default s'exécutait immédiatement, et le processeur était chargé à 100%, au lieu d'attendre des événements des canaux.