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.
- Levantando un runtime pequeño (p. ej., Tokio de un solo hilo, smol, pollster) y usando
- 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_onenstd(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.
- Un executor mínimo o
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
Movey 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_onen 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.