Pola untuk permintaan dengan waktu respons yang lama?

7

Kami saat ini memelihara "server web" python buatan sendiri di mana menghasilkan respons untuk beberapa permintaan dapat memakan waktu yang sangat lama sebagian besar karena perhitungan yang berat - permintaan ini pada dasarnya adalah posting dengan batas waktu sangat lama (pikirkan menit hingga puluhan menit).

Salah satu masalah arsitektur ini adalah kadang-kadang ada kebutuhan untuk membatalkan permintaan seperti itu - misalnya pengguna melihat kesalahan saat mengonfigurasi permintaan. Saat ini, pembatalan adalah permintaan lain, yang membatalkan permintaan yang sudah berjalan lama - tetapi ada banyak celah, misalnya apa yang terjadi jika klien hanya menutup situs web?

Saat ini, kami berencana untuk pensiun dari server web yang dibenci dan beralih ke sesuatu yang masuk akal - misalnya Flask yang berjalan di dalam IIS menggunakan wfastcgi. Karena alasan politik, IIS diatur, jadi beralih ke sesuatu seperti gunicorn keluar dari jendela.

Semua pengembangan terhenti karena tidak ada yang punya ide, bagaimana cara membunuh proses yang dijalankan oleh (w) fastcgi - kekhawatiran itu sama sekali bukan bagian dari spesifikasi fastcgi.

Perasaan saya adalah, bahwa upaya untuk membangun sesuatu yang menggabungkan itu adalah kesalahan - saya lebih suka solusi di mana server hanya membongkar tugas-tugas intensif komputasi seperti ke beberapa server latar belakang (labu + seledri?) Dan jajak pendapat front-end untuk itu.

Sayangnya, solusi lama sudah ada begitu lama sehingga beberapa devs ingin mempertahankan perilaku di semua biaya.

Menjadi bukan seorang web server saya ingin beberapa tips / pola apa solusi yang masuk akal untuk masalah seperti itu bisa terlihat.

Sauer Kristen
sumber

Jawaban:

8

Apa yang Anda sarankan itu benar.

Seharusnya tidak sinkron.

Anda dapat memposting permintaan dan permintaan memberi Anda ID unik. Ini memposting Selesai pada ID unik ini di beberapa toko tempat Anda dapat melakukan polling.

Jika Anda perlu membatalkan permintaan, permintaan membatalkan menggunakan ID yang sama harus diposting.

Juga di bagian belakang di mana komputasi ini berjalan, misalnya dalam antarmuka yang dijalankan dari Thread (gaya java), Anda dapat memeriksa setiap beberapa detik jika proses dibatalkan dengan memeriksa apakah posting yang dibatalkan telah diminta. Jika ya, maka utas harus keluar. Ini adalah jalan keluar yang bersih. Anda juga bisa menggunakan interupsi ke utas.

Pelajar_101
sumber
IMHO solusi ini adalah yang paling cocok dengan pendekatan 'stateless' yang cocok dengan Http - Anda memisahkan tindakan melakukan perhitungan dari komunikasi permintaan / respons. Dalam pola ini komunikasi permintaan / tanggapan menjadi percakapan seperti ini: 'tolong mulai .. oke saya akan .. bagaimana Anda melanjutkan? .. masih bekerja .. tolong batalkan .. oke saya batalkan .. bagaimana Anda melanjutkan? .. perhitungan dibatalkan .. silakan mulai ... (tunggu) .. bagaimana Anda melanjutkan? .. perhitungan selesai di sini adalah hasilnya. '
Robert
2

Saya sarankan Anda melihat ke wsgi dan menggunakan multithreading . Anda dapat mengelola setiap permintaan di utas, dan menerapkan batas waktu di utas. Anda juga harus dapat mengelola utas dan membatalkan permintaan dengan lebih mudah.

Tereus Scott
sumber
1

Masalah yang saat ini Anda hadapi dengan posting HTTP sederhana tidak dapat diselesaikan dalam protokol itu. HTTP berfungsi secara sinkron di client / server yang ketat sehingga tidak ada notifikasi sisi server dan tidak ada pembatalan asli. Selain itu, Anda akan menghadapi masalah jawaban yang hilang karena batas waktu jaringan internet. Saya akan menyarankan pendekatan yang berbeda dan modern. Penafian: dukungan browser kurang dari 90%

Saya sarankan Anda membalikkan arus informasi dan menggunakan soket web. Apa yang perlu Anda lakukan setelah tugas selesai adalah memberi tahu pengguna Anda dan mendorong pemberitahuan dari server ke klien.

Ketika tugas diposting, atau, lebih tepatnya, sebagai pengganti posting, buka websocket (gunakan teknologi server yang Anda sukai, tornado, gevent, python-websocket dll.). Kaitkan utas tugas di acara buka server websocket. Jika klien berhenti, klien akan mengirim acara dekat ke penangan websocket Anda, sehingga Anda dapat mengakhiri utas yang terkait dengannya. Lain, jika tugas Anda berakhir secara normal, server dapat mengirim data ke klien dan menutup websocket. Anda juga harus membuat server melakukan ping sekali setiap 30-an karena soket web ditutup jika tidak aktif selama lebih dari satu menit.

Jika Anda menerapkan ini, ini akan menjadi lebih cepat dan lebih bersih daripada pemungutan suara sisi klien, sambil memecahkan masalah kesenjangan karena Anda memiliki saluran bidirectionnal nyata. Perhatikan bahwa Anda dapat mengimplementasikan layanan tambahan di atas skema tugas seperti sesi, ping progres, dll.

Arthur Havlicek
sumber
0

Jika tugas Anda membutuhkan banyak waktu untuk dikerjakan, jangan lakukan itu atas permintaan itu. Antri itu dan buat beberapa proses lain yang akan melakukan pekerjaan.

Setelah pekerjaan selesai, cukup kirimkan pemberitahuan kepada pengguna bahwa "operasi x" sudah selesai, sementara itu tunjukkan pesan "pekerjaan Anda akan selesai sekitar x menit".

Djuro
sumber