Los tiempos de espera (Timeouts) son importantes para programas que se conectan a recursos
externos
o que de
otra
manera necesitan limitar el tiempo de ejecución. Implementar tiempos de espera en Go es fácil y elegante
gracias a los
canales y select .
|
|
|
package main
|
|
import (
"fmt"
"time"
)
|
|
func main() {
|
Para nuestro ejemplo, supongamos que estamos ejecutando una llamada externa que devuelve su resultado en un
canal
c1 después de 2s. Observa que el canal está bufferizado, por lo que el envío en la goroutine es
no
bloqueante. Este es un patrón común para prevenir fugas de goroutines en caso de que el canal nunca se lea.
|
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c1 <- "result 1"
}()
|
Aquí está el select implementando un tiempo de espera. res := <-c1 espera el
resultado y
<-time.After espera un valor que se envíe después del tiempo de espera de 1s. Dado que
select procede con la primera recepción que esté lista, tomaremos el caso de tiempo de espera
si la
operación tarda más de 1s permitido.
|
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(1 * time.Second):
fmt.Println("timeout 1")
}
|
Si permitimos un tiempo de espera más largo de 3s, entonces la recepción desde c2 tendrá éxito
y imprimiremos el resultado.
|
c2 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(3 * time.Second):
fmt.Println("timeout 2")
}
}
|