Rust asíncrono

En Rust, la programación asíncrona se basa en el concepto de futuros para representar operaciones potencialmente de larga duración que podrían no completarse de inmediato. Estos futuros necesitan un mecanismo para impulsar su ejecución y finalización. Aquí es donde entran en juego los ejecutores asíncronos.

Un ejecutor asíncrono es responsable de administrar y ejecutar estos futuros. Proporciona un entorno en el que se pueden programar los futuros, se puede consultar su progreso y, en última instancia, se puede impulsar su finalización. Piensa en él como un orquestador que controla las complejidades de las tareas asíncronas, lo que permite que tu código siga siendo responsivo y eficiente.

Rust ofrece varios ejecutores asíncronos, cada uno con sus propias fortalezas y características.

Ejecutores asíncronos

La elección del ejecutor para tu servicio de Rust depende en gran medida de la naturaleza de su carga de trabajo. Si bien Tokio es un potente entorno de ejecución asíncrono, es posible que no sea la solución óptima para todas las situaciones.

En el caso de los servicios que ejecutan principalmente operaciones secuenciales, la introducción de un entorno de ejecución asíncrono como Tokio puede generar una sobrecarga innecesaria sin proporcionar ganancias de rendimiento significativas. En esos casos, un ejecutor de un solo subproceso podría ser una opción más adecuada y liviana. Este enfoque simplifica la base de código y reduce el consumo de recursos.

Configura subprocesos de trabajo

Cuando se trata de servicios que tienen operaciones inherentemente simultáneas o asíncronas, aprovechar las capacidades de un entorno de ejecución asíncrono como Tokio se vuelve fundamental. Para maximizar el rendimiento en estas situaciones, configura el entorno de ejecución para que use una cantidad de subprocesos de trabajo que coincida con la cantidad de núcleos de CPU disponibles en el sistema. Esto permite que el entorno de ejecución distribuya de manera eficiente la carga de trabajo y aproveche al máximo la potencia de procesamiento disponible.

Ten en cuenta el entorno general del sistema cuando configures subprocesos de trabajo. Si se ejecutan varios servicios de forma activa en la misma máquina virtual, ajusta la cantidad de subprocesos de trabajo por servicio para evitar el uso excesivo de la CPU y garantizar una asignación justa de recursos entre todos los procesos activos.

Operaciones de bloqueo

Es fundamental asegurarse de que los subprocesos de trabajo dentro de un entorno de ejecución asíncrono nunca se bloqueen por operaciones de larga duración o síncronas. Bloquear un subproceso de trabajo puede dificultar en gran medida la capacidad del entorno de ejecución para procesar las tareas entrantes y mantener la capacidad de respuesta.

Si una función que se ejecuta en un subproceso de trabajo necesita realizar una operación de bloqueo, usa tokio::spawn_blocking. Esta función descarga la operación de bloqueo en un grupo de subprocesos independiente diseñado específicamente para esas tareas, lo que evita cualquier interrupción en los subprocesos de trabajo asíncronos y garantiza la capacidad de respuesta general del servicio.