Python async y tareas vinculadas a la CPU?

Recientemente he estado trabajando en un proyecto para mascotas en python usando un matraz. Es un simple pastebin con soporte de resaltado de sintaxis del lado del servidor con pygments. Debido a que esta es una tarea costosa, delegué el resaltado de sintaxis a una cola de tareas de apio y en el controlador de solicitudes, estoy esperando a que termine. No hace falta decir que esto no hace más que aliviar el uso de la CPU a otro trabajador, porque esperar un resultado todavía bloquea la conexión al servidor web. A pesar de que mis instintos me decían que evitara una optimización prematura como la plaga, todavía no podía evitar mirar asíncrono.

Asíncrono

Si has estado siguiendo el desarrollo web de Python últimamente, seguramente has visto que async está en todas partes. Lo que async hace es devolver la multitarea cooperativa, lo que significa que cada "hilo" decide cuándo y dónde ceder a otro. Este proceso no preventivo es más eficiente que los subprocesos del sistema operativo, pero aún tiene sus inconvenientes. En este momento parece haber 2 enfoques principales:

multitarea de estilo de llamada / eventocoroutines

El primero proporciona la concurrencia a través de componentes acoplados libremente ejecutados en un bucle de eventos. Aunque esto es más seguro con respecto a las condiciones de carrera y proporciona más consistencia, es considerablemente menos intuitivo y más difícil de codificar que la multitarea preventiva.

La otra es una solución más tradicional, más cercana al estilo de programación de subprocesos, ya que el programador solo tiene que cambiar manualmente el contexto. Aunque es más propenso a las condiciones de carrera y los puntos muertos, ofrece una solución fácil de ingresar.

El trabajo más asíncrono en este momento se realiza en lo que se conoce comoIO-enlazado Tareas, tareas que bloquean para esperar entrada o salida. Esto generalmente se logra mediante el uso de funciones basadas en el sondeo y el tiempo de espera que se pueden llamar y, si regresan negativamente, se puede cambiar el contexto.

A pesar del nombre, esto podría aplicarse aEnlazado a la CPU tareas también, que se pueden delegar en otro trabajador (subproceso, proceso, etc.) y luego se pueden esperar sin bloqueos para obtenerlas. Idealmente, estas tareas se escribirían de una manera asíncrona, pero de manera realista esto implicaría separar el código en partes lo suficientemente pequeñas como para no bloquearlas, preferiblemente sin dispersar los cambios de contexto después de cada línea de código. Esto es especialmente inconveniente para las bibliotecas síncronas existentes.

Debido a la conveniencia, me decidí a usar gevent para el trabajo asíncrono y me preguntaba cómo afrontar las tareas relacionadas con la CPU en un entorno asíncrono (¿usar futuros, apio, etc.?).

¿Cómo utilizar modelos de ejecución asíncronos (gevent en este caso) con marcos web tradicionales como matraz? ¿Cuáles son algunas de las soluciones comúnmente acordadas para estos problemas en python (futuros, colas de tareas)?

EDITAR: Para ser más específicos: ¿Cómo usar gevent con el matraz y cómo tratar las tareas relacionadas con la CPU en este contexto?

EDIT2: Teniendo en cuenta cómo Python tiene la GIL que impide la ejecución óptima del código de subprocesos, esto deja solo la opción de multiprocesamiento, al menos en mi caso. Esto significa que ya sea utilizandoconcurrent.futures o algún otro servicio externo que se ocupe del procesamiento (puede abrir las puertas incluso para algo que no sea lenguaje). ¿Cuáles serían, en este caso, algunas soluciones populares o de uso frecuente con gevent (es decir apio)? - mejores prácticas

Respuestas a la pregunta(2)

Su respuesta a la pregunta