Cancelación

Si eliminas un futuro, no se podrá volver a sondear. Este fenómeno se denomina cancelación y puede producirse en cualquier momento de await. Hay que tener cuidado para asegurar que el sistema funcione correctamente, incluso cuando se cancelen los futuros. Por ejemplo, no debería sufrir interbloqueos o perder datos.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Speaker Notes

This slide should take about 18 minutes.
  • El compilador no ayuda con la seguridad de la cancelación. Debes leer la documentación de la API y tener en cuenta el estado de tu async fn.

  • A diferencia de panic y ?, la cancelación forma parte del flujo de control normal (en contraposición a la gestión de errores).

  • En el ejemplo se pierden partes de la cadena.

    • Cuando la rama tick() termina primero, se eliminan next() y su buf.

    • LinesReader se puede configurar para que no se cancele marcando buf como parte del struct:

      #![allow(unused)] fn main() { struct LinesReader { stream: DuplexStream, bytes: Vec<u8>, buf: [u8; 1], } impl LinesReader { fn new(stream: DuplexStream) -> Self { Self { stream, bytes: Vec::new(), buf: [0] } } async fn next(&mut self) -> io::Result<Option<String>> { // prefijo buf y bytes con self. // ... let raw = std::mem::take(&mut self.bytes); let s = String::from_utf8(raw) .map_err(|_| io::Error::new(ErrorKind::InvalidData, "not UTF-8"))?; // ... } } }
  • Interval::tick es a prueba de cancelaciones, ya que registra si una marca se ha ‘entregado’.

  • AsyncReadExt::read es a prueba de cancelaciones porque o devuelve los datos o no los lee.

  • AsyncBufReadExt::read_line es similar al ejemplo y no está configurado a prueba de cancelaciones. Consulta su documentación para obtener información detallada y alternativas.