Bisakah seorang penelepon membatalkan eksekusi kode yang diminta oleh permintaan HTTP?

8

Pihak ketiga yang akan membuat permintaan HTTP ke API yang saya bangun, mensyaratkan bahwa API merespons dalam waktu kurang dari satu detik. Pertanyaan saya adalah, apakah mereka memiliki cara (secara harfiah cara apa pun , dalam batas protokol http dan / atau tcp / ip) untuk membatalkan eksekusi kode saya jika perlu waktu lebih dari satu detik?

torehan
sumber
1
Mereka dapat mengatur batas waktu HttpClient secara langsung, tetapi itu tidak membatalkan kode yang berjalan di sisi server.
Jon Raynor
15
Iya. IP geolokasi dan rudal jelajah. Jika bukan itu yang ada dalam pikiran Anda, Anda harus mendapatkan jauh lebih tepat dengan "cara apa pun" Anda.
Jörg W Mittag
Mungkin ada puluhan alasan yang dapat "membuat belive" pengguna bahwa proses ini memakan waktu lebih dari 1 detik. Misalnya, latensi. Anda tahu, seseorang di kantor mengunduh konten yang mencurigakan ... Pada saat pengguna mengirim permintaan pembatalan, prosesnya bisa selesai dengan sukses. 1 detik adalah sedikit waktu (saya pikir) untuk manusia.
Laiv
@ jmoreno apakah "batas" Anda termasuk saya menambahkan tombol batal bagi pengguna untuk mengklik? Atau Anda mencari sesuatu yang lebih rendah di tumpukan osi daripada lapisan aplikasi?
candied_orange
2
Terkejut ini sebenarnya VTC. Jawabannya pasti. Tidak ada yang mencegah Anda mendaftarkan permintaan dengan cara tertentu dan menambahkan titik akhir atau metode API yang membatalkannya - baik melalui manajemen proses asli atau dengan meminta "dibatalkan" secara berkala memeriksa apakah permintaan tersebut diperintahkan untuk berhenti ...
svidgen

Jawaban:

10

HTTP tidak berfungsi seperti itu. Klien mengirim permintaan, lalu server mengirim balasan. Tidak ada komunikasi lain yang terjadi. Nah, server dapat mengirim respons informasi 1xx sebelum respons utama. Tetapi tidak ada cara bagi klien untuk mengirim pembaruan tentang permintaan yang dikirim.

(Situasinya sangat berbeda untuk HTTP / 2 yang dapat mengalikan banyak permintaan melalui koneksi yang sama. Seorang klien dapat MEMBATALKAN aliran untuk menunjukkan bahwa ia tidak lagi diperlukan setelah menerima PUSH_PROMISE dari server. Saya akan mengabaikan HTTP / 2 untuk sisa jawaban ini.)

Juga, jaringan tidak berfungsi seperti itu. Secara khusus, lihat kekeliruan kedua dari komputasi terdistribusi : "latency adalah nol". Bukan itu. Dari batas waktu satu detik itu, 400 ms mungkin telah dihabiskan untuk membangun koneksi dan mengirimkan permintaan dan 600 ms pada tanggapan, karena salah satu paket dijatuhkan dan Anda harus mengirim ulang semuanya dan klien Anda ada di Australia. Selain masalah bahwa server mungkin tidak memiliki cukup waktu, server bahkan tidak tahu berapa banyak waktu yang mereka miliki karena latensi respons tidak dapat diketahui sebelumnya.

Jadi mengingat secara harfiah menerapkan batas waktu ini tidak mungkin, solusi apa yang mungkin cukup baik?

Jika respons tidak akan memiliki nilai setelah batas waktu, klien dapat dengan mudah menutup koneksi. Ini akan menyebabkan respons Anda diabaikan, tetapi tidak akan mencegah respons.

Menutup koneksi TCP di mana permintaan HTTP dikirim tidak memberi tahu server. Tetapi pemberitahuan ini hanya datang dengan latensi, jadi mungkin sudah terlambat. Juga, kerangka kerja web Anda mungkin tidak melakukan apa-apa ketika soket klien ditutup. Dalam hal ini Anda hanya akan mendapatkan "koneksi reset oleh rekan" kesalahan setelah Anda mencoba menulis ke soket tertutup.

Jika Anda tidak ingin menghabiskan lebih dari satu detik untuk memproses respons, menerapkan batas waktu itu sepenuhnya menjadi tanggung jawab Anda, dan tidak ada hubungannya dengan jaringan atau HTTP.

Anda dapat meminta klien untuk memberikan batas waktu ke server, sehingga server dapat membatalkan jika tidak memenuhi tenggat waktu. Ini dapat ditentukan sebagai tajuk khusus, atau sebagai parameter kueri di URL. Batas waktu ini harus menjadi titik waktu absolut dan bukan durasi sehingga penundaan transmisi juga menghabiskan waktu yang tersedia. Tetapi akurasi sub-detik sulit: server dan klien harus disinkronkan dengan waktu yang tepat dan perlu menggunakan jam yang sesuai. Bergantung pada pengaturannya, setiap sumber waktu mungkin mati 100 ms meskipun dikonfigurasi dengan benar. Ini sudah memakan sebagian besar anggaran waktu Anda.

amon
sumber
Tentu saja Anda dapat mengirim batas waktu sebagai waktu relatif - itu berarti server tidak dapat berhenti memproses x detik setelah Anda mengirim permintaan, tetapi hanya x detik setelah server menerimanya. Mungkin lebih baik jika Anda tidak dapat menjamin bahwa jam Anda dan jam server adalah sama. Jika mereka terpisah dua menit, semua permintaan dengan batas waktu satu menit (dalam waktu absolut) mungkin ditolak.
gnasher729
1

Saya kira mereka dapat menutup koneksi, tetapi saya tidak tahu apakah itu benar-benar akan menyebabkan kode Anda dibatalkan - itu akan tergantung pada bagaimana kode Anda ditulis.

Mereka juga dapat mengirim pesan lain yang bisa berarti "Anda terlalu lama jadi jangan repot-repot" tetapi dalam hal ini, Anda mungkin sudah siap untuk menangani pesan CANCEL_REQUEST yang eksplisit.

FrustratedWithFormsDesigner
sumber
Saya pikir menulis ke port tertutup akan memberi sinyal, tetapi tentu saja Anda dapat mengabaikan atau menangani sinyal itu (saya hanya tahu ini dari sisi klien, di mana masalah ini akan membuat klien crash jika Anda tidak menanganinya). Selain itu, klien tidak dapat memaksa server untuk melakukan apa pun. Tentu saja server dapat membatalkan pekerjaannya secara sukarela jika port ditutup, atau membatalkan pekerjaan jika tidak akan dilakukan dalam batas waktu, atau membatalkan pekerjaan jika klien mengirim pesan untuk membatalkan permintaan.
gnasher729