fundo
Estou trabalhando em um aplicativo actix-web usando diesel através de r2d2 e não tenho certeza de como fazer consultas assíncronas da melhor maneira. Encontrei três opções que parecem razoáveis, mas não tenho certeza de qual é a melhor.
Soluções Potenciais
Ator de sincronização
Por um lado, eu poderia usar o exemplo actix , mas é bastante complicado e requer uma boa dose de clichê para construir. Espero que exista uma solução mais razoável.
Actix_web::web::block
Como outra opção, eu poderia usar o actix_web::web::block
para agrupar minhas funções de consulta em um futuro, mas não tenho certeza das implicações de desempenho disso.
A consulta está sendo executada no mesmo sistema Tokio? Pelo que pude encontrar na fonte, ele cria um encadeamento no pool de encadeamentos actix-web subjacente . Isso é um problema?
Se eu ler o código corretamente, o r2d2 bloqueia seu encadeamento ao adquirir uma conexão, o que bloquearia parte do pool principal do actix-web. Mesmo com consultas de banco de dados. Isso bloquearia todo o actix-web se eu fizer mais consultas do que ter threads nesse pool? Se assim for, grande problema.
Futuros-cpupool
Finalmente, a aposta segura que pode ter uma sobrecarga desnecessária é o cpupool de futuros . A questão principal é que isso significa adicionar outra caixa ao meu projeto, embora eu não goste da ideia de vários pools de CPUs flutuando no meu aplicativo desnecessariamente.
Como o r2d2 e o diesel bloquearão, há uma quantidade surpreendente de coisas complicadas aqui.
Mais importante, não compartilhe esse cpupool com nada que não esteja usando o mesmo pool r2d2 (pois todos os threads criados podem bloquear a espera de uma conexão r2d2, bloqueando todo o pool quando houver trabalho).
Em segundo lugar (um pouco mais óbvio), você não deveria ter mais conexões r2d2 do que threads no pool e vice-versa, pois a maior desperdiçaria recursos (conexões não utilizadas / threads constantemente bloqueadas) (talvez mais um thread, talvez mais rápido transferência de conexão pelo agendador do SO em vez do agendador do cpupool).
Por fim, lembre-se do banco de dados que você está usando e do desempenho que você tem lá. A execução de uma única conexão r2d2 e um único encadeamento no pool pode ser melhor em um aplicativo sqlite pesado de gravação (embora eu recomende um banco de dados adequado para isso).
Respostas antigas
Soluções antigas que podem funcionar
https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/
Em essência, recomenda Futures-cpupool.
Qual é a melhor abordagem para encapsular E / S de bloqueio no futuro-rs?
Recomenda o Futures-cpupool para casos gerais.
Soluções antigas que não funcionam
https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/
Uma correção muito boa para uma versão antiga do actix-web. Pelo que posso encontrar, os pedidos não têm mais um conjunto de CPUs.
futures-cpupool
é a solução alternativa recomendada para a falta deasync
suporte no Diesel.