Haruskah diesel dijalankan menggunakan aktor sinkronisasi, actix_web :: web :: block atau futures-cpupool?

10

Latar Belakang

Saya sedang mengerjakan aplikasi actix-web menggunakan diesel melalui r2d2 dan tidak yakin bagaimana cara terbaik membuat pertanyaan asinkron. Saya telah menemukan tiga opsi yang tampaknya masuk akal, tetapi tidak yakin mana yang terbaik.

Solusi Potensial

Sinkronkan Aktor

Untuk satu saya bisa menggunakan contoh actix , tetapi cukup rumit dan membutuhkan banyak boilerplate untuk membangun. Saya harap ada solusi yang lebih masuk akal.

Actix_web::web::block

Sebagai pilihan lain saya bisa menggunakan actix_web::web::blockuntuk membungkus fungsi kueri saya ke masa depan, tapi saya tidak yakin dengan implikasi kinerja ini.

Apakah kueri itu berjalan di sistem Tokio yang sama? Dari apa yang bisa saya temukan di sumbernya, ia membuat thread di threadpool actix-web yang mendasarinya . Apakah itu masalah?

Jika saya membaca kode yang benar, r2d2 memblokir utasnya saat mendapatkan koneksi, yang akan memblokir bagian dari kumpulan inti actix-web. Sama dengan permintaan basis data. Ini kemudian akan memblokir semua web actix jika saya melakukan lebih banyak pertanyaan daripada saya memiliki utas di kolam itu? Jika demikian, masalah besar.

Futures-cpupool

Akhirnya, taruhan aman yang mungkin memiliki beberapa overhead yang tidak dibutuhkan adalah futures-cpupool . Masalah utama adalah bahwa ini berarti menambahkan peti lain ke proyek saya, meskipun saya tidak suka gagasan beberapa cpu-pool yang beredar di aplikasi saya tidak perlu.

Karena r2d2 dan diesel akan memblokir, ada banyak hal rumit di sini.

Yang paling penting, jangan bagikan cpupool ini dengan apa pun yang tidak menggunakan kumpulan r2d2 yang sama (karena semua utas yang dibuat mungkin saja memblokir menunggu koneksi r2d2, mengunci seluruh kumpulan ketika ada pekerjaan).

Kedua (sedikit lebih jelas), Anda seharusnya tidak memiliki lebih banyak koneksi r2d2 daripada thread di pool dan sebaliknya karena yang lebih besar akan menghabiskan sumber daya (koneksi yang tidak digunakan / thread terus-menerus diblokir) (mungkin satu thread lebih, untuk mungkin lebih cepat penyerahan koneksi oleh scheduler OS daripada scheduler cpupool).

Akhirnya, pikirkan database apa yang Anda gunakan dan kinerja yang Anda miliki di sana. Menjalankan koneksi tunggal r2d2 dan satu utas di kolam mungkin yang terbaik dalam aplikasi sqlite tulis berat (meskipun saya akan merekomendasikan database yang tepat untuk itu).

Jawaban lama

Solusi lama yang mungkin berhasil

https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/

Intinya, merekomendasikan Futures-cpupool.

Apa pendekatan terbaik untuk merangkum memblokir I / O di masa depan-rs?

Merekomendasikan Futures-cpupool untuk kasus umum.

Solusi lama yang tidak berhasil

https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/

Perbaikan yang sangat bagus untuk versi actix-web yang lama. Dari apa yang saya dapat menemukan permintaan tidak lagi memiliki cpu-pool di dalamnya.

logina
sumber
Dari komentar dalam masalah ini , sepertinya futures-cpupooladalah solusi yang disarankan untuk kurangnya asyncdukungan di Diesel.
Jmb
Itu lebih merupakan solusi umum. Saya berharap sesuatu yang akan memanfaatkan sistem actix. Meskipun demikian, saya akan menggali futures-cpupool sekarang untuk mencari masalah.
logina
Selamat Datang di Stack Overflow! Sepertinya pertanyaan Anda mungkin dijawab dengan jawaban Apa pendekatan terbaik untuk merangkum memblokir I / O di masa depan-rs? . Jika tidak, harap edit pertanyaan Anda untuk menjelaskan perbedaannya. Kalau tidak, kita dapat menandai pertanyaan ini sebagaimana telah dijawab.
Shepmaster
Karena cpupool juga berinteraksi dengan kumpulan koneksi pemblokiran di r2d2, saya tidak yakin bagaimana cara terbaik untuk menyelesaikannya. Saya melihatnya sendiri sekarang dan akan segera memperbaruinya.
logina

Jawaban:

3

Saya pergi dengan futures-cpupool. Ini adalah solusi terbaik karena pemblokiran interaksi saya.

Menggunakan actix_web :: web :: block cukup baik, tetapi akan menggunakan thread-pool bersama di actix (dan karena panggilan pemblokiran saya menggunakan ini dapat memblokir seluruh pool thread dan mengganggu tugas-tugas lain yang diberikan ke actix_web).

Lebih baik menggunakan futures-cpupool untuk membuat threadpool terpisah per basis data hanya untuk interaksi basis data. Dengan cara ini Anda mengelompokkan semua tugas yang perlu menunggu satu sama lain (ketika ada lebih banyak tugas daripada koneksi) ke dalam satu kumpulan, mencegah mereka memblokir tugas-tugas lain yang tidak memerlukan koneksi dan berpotensi membatasi jumlah utas ke jumlah koneksi (sehingga tugas hanya akan dijadwalkan ketika tidak akan diblokir).

Dalam kasus di mana Anda hanya ingin menggunakan satu koneksi basis data (atau sangat sedikit) aktor sinkronisasi adalah opsi yang cukup bagus. Ini akan bertindak seperti futures-cpupool dengan satu utas, memastikan bahwa semua tugas dijalankan satu per satu, kecuali bahwa itu akan menggunakan salah satu utas yang mendasari actix-web daripada yang terpisah (oleh karena itu, hanya bagus untuk koneksi yang sangat sedikit) . Saya menemukan pelat terlalu besar untuk menjadi layak, meskipun.

logina
sumber
6
baca temuan saya di atas - harap cantumkan informasi yang relevan dengan jawaban dalam jawaban , bukan pertanyaan.
Shepmaster