sfondo
Sto lavorando a un'applicazione actix-web che utilizza diesel tramite r2d2 e non sono sicuro di come effettuare query asincrone al meglio. Ho trovato tre opzioni che sembrano ragionevoli, ma non sono sicuro di quale sia la migliore.
Soluzioni potenziali
Sync Actor
Per prima cosa potrei usare l'esempio actix , ma è abbastanza complicato e richiede una buona dose di boilerplate per essere costruito. Spero che esista una soluzione più ragionevole.
Actix_web::web::block
Come altra opzione potrei usare il actix_web::web::block
per avvolgere le mie funzioni di query in un futuro, ma non sono sicuro delle implicazioni sulle prestazioni di questo.
La query è quindi in esecuzione nello stesso sistema Tokio? Da quello che ho potuto trovare nella fonte, crea un thread nel threadpool actix-web sottostante . È un problema?
Se leggo bene il codice, r2d2 blocca il suo thread quando acquisisce una connessione, che bloccherebbe parte del pool actix-web core. Lo stesso con le query del database. Questo bloccherebbe quindi tutto actix-web se faccio più query di quante ne abbia thread in quel pool? Se è così, grosso problema.
Futures-cpupool
Infine, la scommessa sicura che può avere alcune spese generali non necessarie è futures-cpupool . Il problema principale è che questo significa aggiungere un'altra cassa al mio progetto, anche se non mi piace l'idea di più pool di CPU che fluttuano inutilmente nella mia applicazione.
Poiché sia la r2d2 che il diesel si bloccano, ci sono una quantità sorprendente di cose difficili qui.
Soprattutto, non condividere questo cpupool con qualcosa che non utilizza lo stesso pool r2d2 (poiché tutti i thread creati potrebbero bloccare l'attesa di una connessione r2d2, bloccando l'intero pool quando esiste lavoro).
In secondo luogo (un po 'più ovviamente), quindi non dovresti avere più connessioni r2d2 rispetto ai thread nel pool e viceversa poiché quella più grande sprecherebbe risorse (connessioni non utilizzate / thread costantemente bloccati) (forse un altro thread, forse più veloce passaggio di connessione dallo scheduler del sistema operativo anziché dallo scheduler cpupool).
Infine, ricorda quale database stai utilizzando e le prestazioni che hai lì. Eseguire una singola connessione r2d2 e un singolo thread nel pool potrebbe essere la cosa migliore in un'applicazione sqlite pesante di scrittura (anche se consiglierei un database adeguato per tale).
Vecchie risposte
Vecchie soluzioni che potrebbero funzionare
https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/
In sostanza, raccomanda Futures-cpupool.
Qual è l'approccio migliore per incapsulare l'I / O di blocco in future-rs?
Raccomanda Futures-cpupool per casi generali.
Vecchie soluzioni che non funzionano
https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/
Una soluzione davvero piacevole per una vecchia versione di actix-web. Da quello che posso trovare le richieste non contengono più un pool di CPU.
futures-cpupool
sia la soluzione alternativa raccomandata per la mancanza diasync
supporto in Diesel.