Ir (lenguaje de programación): ¿Cómo puedo dejar de recibir de un canal que envía datos continuamente, después de un cierto tiempo?

Aquí hay un ejemplo de una función que recibe de un canal en un bucle, pero se da por vencida después de cierto tiempo:

Versión común

func process(channel <-chan Result, timeout time.Duration)
timer := time.NewTimer(timeout)
defer timer.Stop() for {
select {
case value, ok := <-channel:
if !ok {
return
}
doSomething(value)
case <-timer.C:
return
}
}
}

func process(channel <-chan Result, timeout time.Duration)
timer := time.NewTimer(timeout)
defer timer.Stop() for {
select {
case value, ok := <-channel:
if !ok {
return
}
doSomething(value)
case <-timer.C:
return
}
}
}

Algunas notas sobre por qué funciona de la manera que lo hace:

  • Observe que el canal es de tipo <-chan ... , lo que significa que solo se puede usar para operaciones de recepción. Esta es una buena práctica al pasar canales a un receptor, de forma análoga al uso de const en C ++. Evita algunos errores simples como llamar a close() en el lado del receptor. Solo el lado del remitente debe cerrar un canal, porque necesita saber que ya no debe enviarlo, o de lo contrario entrará en pánico.
  • Está escrito como una función autónoma, porque aclara la lógica para romper tanto la select como el bucle. Podría usar etiquetas para hacer esto, pero casi siempre es el caso de que un bucle que es lo suficientemente complejo como para necesitar etiquetas es lo suficientemente complejo como para necesitar encapsularse en una función.
  • El defer timer.Stop() es opcional, pero es una buena práctica siempre que use temporizadores. Significa que si la función regresa antes de que expire el temporizador, ya no pagará el costo de los recursos del temporizador. De lo contrario, la rutina del temporizador seguirá existiendo después de que regrese la función, lo que puede ser un problema si está llamando a process() en un ciclo cerrado.

Versión Ultra-pedante

Lo anterior es un patrón común que verá, pero técnicamente es sutilmente defectuoso. Si el canal siempre está listo para recibir, es posible (aunque exponencialmente improbable) que el ciclo nunca se agote. Esto se debe a que si hay varios casos en una select listos, el tiempo de ejecución de Go elegirá uno de ellos de forma seudoaleatoria .

Esto es una gran sorpresa para muchos, pero dado que la probabilidad de continuar es de 1/2 en cada iteración, en la práctica solo verá una o dos iteraciones adicionales, lo que nunca notará si su condición de detención se basa en el tiempo .

Sin embargo, generalmente agrego una segunda verificación de tiempo de espera en la parte superior del ciclo para evitar esto, porque creo en escribir código que haga lo que pretendía de manera determinista, en lugar de solo con una probabilidad muy muy muy alta.

func process(channel <-chan Result, timeout time.Duration)
timer := time.NewTimer(timeout)
defer timer.Stop()

para {
seleccione {
case <-timer.C:
regreso
defecto:
}

seleccione {
valor del caso, ok: = <-canal:
si! ok {
regreso
}
hacer algo (valor)
case <-timer.C:
regreso
}
}
}

El default: case en la primera select convierte en una comprobación sin bloqueo. Si el temporizador no ha expirado, simplemente fallará de inmediato.

More Interesting

Quiero ser un desarrollador de software, ¿qué justificaría comprar la Mac más cara?

¿Es cierto que la mayoría de los desarrolladores de software no tienen tiempo hasta la fecha, ya que ya pasan la mayor parte de su tiempo trabajando y aprendiendo?

Soy un desarrollador de copiar y pegar, ¿cómo me convierto en un verdadero desarrollador de software?

¿Cuáles son los beneficios para el desarrollo de software para la industria de la salud?

¿Qué características de Java apasionan a las personas?

¿Por qué se supone que un desarrollador de software piensa como un tomador de decisiones empresariales?

¿Cuál es el alcance para la programación y el desarrollo de software en el futuro (aproximadamente 20 años)?

¿Cuál es su historia de desarrollo de software desde una carrera más fresca a una profesional?

¿Es Francia un buen lugar para que viva un desarrollador de software indio?

Dado que la tecnología informática evoluciona tan rápidamente, ¿importa si tiene 5 o 15 años de experiencia como, por ejemplo, desarrollador de software?

¿Qué porcentaje de desarrolladores de software profesionales aprendieron a codificar en un aula?

Como hay muchos tipos de desarrolladores de software, ¿podría contarme sobre su área de especialización?

¿Qué habilidad es más importante cuando se busca un puesto de desarrollador de software de nivel de entrada? Pruebas de software o conceptos básicos de Oracle

Readify, Kiandra o Thoughtworks: ¿en cuál es mejor trabajar para un apasionado desarrollador australiano de .NET con sede en Melbourne?

¿Hay un buen trabajo (paquete de 10-12 lakh) para que el ingeniero de software tenga 2 años de experiencia de desarrollador de software en TCS?