La trampa de Tokio y Rayon: por qué async/await falla como modelo de concurrencia

Fuentes: The Tokio/Rayon Trap and Why Async/Await Fails Concurrency

async/await se impuso en la última década porque permite escribir código asíncrono con una sintaxis casi idéntica a la del código síncrono. Sin embargo, bajo esa apariencia familiar se esconde una enorme complejidad estructural: oculta el flujo de control, difumina la realidad del hardware y termina devolviendo al desarrollador la carga de planificar las tareas. El artículo examina por qué esta facilidad aparente se traduce en sistemas difíciles de operar en producción.

El primer problema es que async/await mezcla dos conceptos distintos: la asincronía (ceder el control mientras se espera una operación de E/S) y la concurrencia (atender varias cosas a la vez). La sintaxis disfraza máquinas de estado intercaladas como si fueran hilos aislados. En un ejecutor cooperativo como Tokio o el de Node.js, el hilo no cede hasta llegar a un punto await, de modo que una tarea intensiva de CPU bloquea todo el hilo y dispara la latencia de miles de peticiones de red, mientras el hardware permanece casi ocioso.

Cuando aparecen estos picos, la receta habitual consiste en separar los entornos: Tokio para E/S y un grupo de hilos dedicado, como Rayon, para cálculo. Equipos de ingeniería en PostHog y Meilisearch han documentado lo doloroso que resulta mantener esa partición en producción. Si el desarrollador debe decidir manualmente qué función va a cada grupo y orquestar el paso de mensajes entre dos modelos mentales distintos, la abstracción async ha fracasado: ha convertido al programador en un planificador humano dentro del bucle.

El segundo fallo es que los entornos async hacen demasiado fácil la capacidad ilimitada. Tareas en vuelo se acumulan sin tope, la memoria crece hasta que el sistema operativo mata el proceso por OOM. Las colas no resuelven la sobrecarga, solo retrasan el crash. Además, los planificadores work-stealing, pensados para repartir la carga, destruyen la localidad de caché: WhatsApp documentó cómo, en máquinas con más de cien núcleos, los hilos空闲 peleaban por un lock global y penalizaban el rendimiento con accesos a memoria principal.

Como alternativa, el autor presenta Project Tina, un framework de concurrencia thread-per-core, shared-nothing, sin async ni await, con memoria y buzones estrictamente acotados, sin robo de trabajo y con simulación determinista para reproducir fallos. La propuesta sustituye la magia del runtime por garantías estructurales: predecibilidad frente a brevedad.