Antecedentes
Estoy trabajando en una aplicación web actix que usa diesel a través de r2d2 y no estoy seguro de cómo hacer mejor las consultas asincrónicas. He encontrado tres opciones que parecen razonables, pero no estoy seguro de cuál es la mejor.
Soluciones potenciales
Sincronizar actor
Por un lado, podría usar el ejemplo actix , pero es bastante complicado y requiere una buena cantidad de repeticiones para construir. Espero que exista una solución más razonable.
Actix_web::web::block
Como otra opción, podría usar actix_web::web::block
para ajustar mis funciones de consulta en un futuro, pero no estoy seguro de las implicaciones de rendimiento de esto.
¿La consulta se ejecuta en el mismo sistema Tokio? Por lo que pude encontrar en la fuente, crea un hilo en el conjunto de hilos actix-web subyacente . ¿Es eso un problema?
Si leo el código correctamente, r2d2 bloquea su hilo cuando adquiere una conexión, lo que bloquearía parte del núcleo del grupo web actix. Lo mismo con las consultas de la base de datos. ¿Esto bloquearía toda la web actix si hago más consultas de las que tengo en ese grupo? Si es así, gran problema.
Futures-cpupool
Finalmente, la apuesta segura que puede tener algunos gastos innecesarios es futures-cpupool . El problema principal es que esto significa agregar otra caja a mi proyecto, aunque no me gusta la idea de que múltiples cpu-pools floten innecesariamente en mi aplicación.
Dado que tanto el r2d2 como el diésel se bloquearán, hay una cantidad sorprendente de cosas difíciles aquí.
Lo que es más importante, no comparta este cpupool con nada que no use el mismo grupo de r2d2 (ya que todos los subprocesos creados pueden bloquear la espera de una conexión de r2d2, bloqueando todo el grupo cuando existe trabajo).
En segundo lugar (un poco más obvio), por lo tanto, no debería tener más conexiones r2d2 que subprocesos en el grupo y viceversa, ya que el más grande desperdiciaría recursos (conexiones no utilizadas / subprocesos constantemente bloqueados) (quizás un subproceso más, para quizás más rápido transferencia de conexión por el planificador del sistema operativo en lugar del planificador cpupool).
Finalmente, tenga en cuenta qué base de datos está utilizando y el rendimiento que tiene allí. Ejecutar una sola conexión r2d2 y un solo subproceso en el grupo podría ser mejor en una aplicación sqlite de escritura pesada (aunque recomendaría una base de datos adecuada para tal).
Viejas respuestas
Viejas soluciones que pueden funcionar
https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/
En esencia, recomienda Futures-cpupool.
¿Cuál es el mejor enfoque para encapsular el bloqueo de E / S en futuros rs?
Recomienda Futures-cpupool para casos generales.
Viejas soluciones que no funcionan
https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/
Una buena solución para una versión anterior de actix-web. Por lo que puedo encontrar, las solicitudes ya no tienen un cpu-pool en ellas.
futures-cpupool
es la solución recomendada para la falta deasync
soporte en Diesel.