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::block
untuk 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.
sumber
futures-cpupool
adalah solusi yang disarankan untuk kurangnyaasync
dukungan di Diesel.Jawaban:
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.
sumber