Un plan de cuatro años para Rust async

Async/await en Rust sigue siendo profundamente polarizante: algunos desarrolladores lo elogian por permitir servicios de red altamente concurrentes y eficientes, mientras que otros lo encuentran ergonómicamente incómodo, “virulento” en las bases de código y mal adaptado a embebidos o a casos de uso más simples. Los comentaristas reaccionan a una hoja de ruta propuesta de cuatro años para Rust async, debatiendo piezas faltantes como async en traits, generadores, un `block_on` estándar, traits agnósticos al runtime y si `std` debería incluir un executor por defecto. Debajo de los puntos técnicos hay una tensión más amplia entre las raíces de Rust en la programación de sistemas y su uso creciente para backends web y de servicios, así como frustración por el ritmo lento y conservador de estabilizar características importantes del lenguaje.

“Contagio” async y soluciones provisionales

  • Muchos se quejan de que, si una dependencia es async, “todo tiene que ser async”.
  • Otros responden que puedes aislar async de la siguiente manera:
    • Levantando un runtime pequeño (p. ej., Tokio de un solo hilo, smol, pollster) y usando block_on.
    • Ejecutando código async en un hilo dedicado y comunicándote mediante canales.
  • Los críticos responden que esto sigue arrastrando runtimes pesados y dependencias extra, lo cual importa para los tiempos de compilación, la confianza y los entornos restringidos.

Ergonomía, complejidad y experiencia real

  • Algunos consideran que Rust async es un gran problema: viral, poco intuitivo, con mucho peso en lifetimes, malos errores del compilador, cierres difíciles e interacciones incómodas con async_trait.
  • Otros informan años de uso fluido en grandes bases de código en producción, argumentando que las quejas están exageradas y a menudo vienen de experiencia limitada o desactualizada.
  • Hay cansancio por los debates recurrentes de “async es difícil/malo” que ignoran los matices del diseño o el artículo enlazado.

Dominios: servidores vs embebidos y sistemas

  • Para servicios de red de alta concurrencia (servidores HTTP, proxies con mucha carga de BD), muchos dicen que async es indispensable para un rendimiento predecible y escalabilidad.
  • Para embebidos y sistemas de bajo nivel, hay división:
    • Algunos evitan async por completo (prefiriendo RTOS, actores, hilos, interrupciones, DMA, bucles de eventos).
    • Otros elogian frameworks como Embassy como sustituto ligero de un RTOS y por su estructuración ergonómica de tareas.

Runtimes, dominio de Tokio y stdlib

  • Tokio ha “ganado” efectivamente el ecosistema; muchas crates dependen fuertemente de él (locks, channels, spawn).
  • Algunos ven esto como un problema cultural y arquitectónico y quieren traits agnósticos al runtime (AsyncRead/Write, Stream, spawn, locks, channels) en std.
  • Las propuestas incluyen:
    • Un executor mínimo o block_on en std (posiblemente al estilo de pollster).
    • No hacer de Tokio el runtime por defecto; al parecer, tanto los mantenedores de Rust como los de Tokio se oponen a eso.

Modelos de concurrencia: hilos, async, green threads

  • Hay debates sobre si async debería ser una característica del lenguaje o un problema de biblioteca/herramientas.
  • Algunos sostienen que un hilo por conexión es suficientemente bueno para la mayoría de las cargas de trabajo y más simple; async principalmente ayuda con enormes números de tareas concurrentes ligadas a IO.
  • Otros argumentan que los green threads / fibers (goroutines al estilo de Go, Java Loom) ofrecen mejor DX que el async “coloreado”, sin infectar APIs.
  • Contraargumento: Rust eliminó previamente los green threads; reintroducirlos con el modelo de seguridad de Rust y las restricciones de embebibilidad no es trivial.

Vacíos en el diseño del lenguaje y planes

  • Puntos de dolor mencionados: complejidad de Pin/Unpin, falta de generadores/iteradores async, historia débil de async en traits (mejorando pronto), ergonomía deficiente para closures async, no hay async drop, falta de tipos lineales/inolvidables.
  • Algunos quieren un trait Move y semántica inamovible por defecto para simplificar async; otros son cautelosos.
  • Los generadores se ven como estrechamente relacionados con async y deseables, pero se debate su impacto real en el mundo real.

Ritmo de evolución de Rust y gobernanza

  • Algunos critican una estabilización “glacial” (p. ej., block_on en std, generadores, correcciones más profundas de async), queriendo plazos de 6 meses en lugar de planes de varios años.
  • Otros defienden una estabilización lenta y conservadora porque las características son, en la práctica, para siempre y deben estar bien antes de congelarlas.