select es una potente construcción de Go para trabajar con canales. Permite esperar la llegada de datos de varios canales o su cierre. Tan pronto como uno de los casos esté listo, se ejecuta la rama correspondiente, mientras que las demás se ignoran en la iteración actual.
ch1 := make(chan int) ch2 := make(chan string) go func() { ch1 <- 42 }() go func() { ch2 <- "hola" }() select { case i := <-ch1: fmt.Println("recibido de ch1:", i) case s := <-ch2: fmt.Println("recibido de ch2:", s) default: fmt.Println("sin comunicación") }
Matices:
¿Qué sucederá si en select ningún canal está listo para leer/escribir y falta el bloque default?
Respuesta: Select se bloqueará hasta que uno de los canales esté listo para la operación.
Historia
Un desarrollador implementó una función de interrupción de flujo de datos a través de select sin bloque default, suponiendo que la función "liberaría el control" después de varios intentos. Los canales permanecieron vacíos y la función se bloqueó indefinidamente en select, llevando a la congestión de los flujos de datos del microservicio.
Historia
Se usó select con varios canales, en algunas goroutines ocurrieron pánicos al cerrar canales no manejados en select, lo que provocó filtraciones y caídas. No se preveron comprobaciones para el cierre del canal (a través de la variable ok).
Historia
En uno de los proyectos, los desarrolladores añadieron un bloque default en select para evitar bloqueos. Pero esto llevó a un bucle ocupado — select se ejecutaba en un bucle, el default se activaba inmediatamente, y el procesador cargaba al 100% en lugar de esperar eventos de los canales.