呼び出し元はHTTPリクエストによって呼び出されたコードの実行を中止できますか?


8

私が作成しているAPIにHTTPリクエストを行うサードパーティは、APIが1秒未満で応答することを要求しています。私の質問は、彼らが道持っているされて(文字通りあらゆるの範囲内で、道をHTTPおよび/またはTCP / IPプロトコル)それは長い1秒以上かかる場合は、私のコードの実行を中止するには?


1
HttpClientのタイムアウトを直接設定できますが、サーバー側で実行されているコードは中止されません。
Jon Raynor 2017

15
はい。IPジオロケーションと巡航ミサイル。それはあなたが考えていたものではありません場合は、取得する必要があります多くのあなたの「文字通りどのような方法」で、より正確な。
イェルクWミッターク

プロセスが1秒より長くかかっていることをユーザーに「信じさせる」ことができる数十の理由が考えられます。たとえば、レイテンシ。オフィスの誰かが不審なコンテンツをダウンロードしています...ユーザーがキャンセルリクエストを送信するまでに、プロセスは正常に終了している可能性があります。1秒は、人間にとっては少しの時間です(私はそう思います)。
Laiv

@jmoreno「境界」には、ユーザーがクリックするためのキャンセルボタンを追加することが含まれますか?または、OSIスタックでアプリケーション層よりも低いものを探していますか?
candied_orange 2018

2
これは実際にはVTCでした。答えは確かです。何らかの方法でリクエストを登録し、リクエストをキャンセルするエンドポイントまたはAPIメソッドを追加することを妨げるものは何もありません-ネイティブプロセス管理を通じて、または「キャンセル可能な」リクエストに停止するように指示されているかどうかを定期的にチェックさせることによって...
svidgen

回答:


10

HTTPはそのようには機能しません。クライアントがリクエストを送信し、サーバーがレスポンスを返します。他の通信は発生しません。サーバーは、メインの応答の前に1xxの情報応答を送信できます。ただし、クライアントが送信済みリクエストに関する更新を送信する方法はありません。

(同じ接続で複数のリクエストを多重化できるHTTP / 2の場合は状況が大きく異なります。サーバーからPUSH_PROMISEを受信した後、クライアントはストリームをキャンセルしてそれが不要であることを示すことができます。HTTP/ 2は無視しますこの答えの残りのために。)

また、ネットワークはそのように機能しません。特に、分散コンピューティングの 2番目の誤り「レイテンシはゼロ」を参照してください。そうではない。その1秒のタイムアウトのうち、接続の確立と要求の送信に400ミリ秒、応答に600ミリ秒が費やされた可能性があります。パケットの1つがドロップされ、すべてを再送信する必要があり、クライアントはオーストラリアにいるためです。サーバーに十分な時間がない可能性があるという問題は別として、サーバーは応答待ち時間を事前に知ることができないため、サーバーがどれだけの時間を持っているかも知りません。

これらのタイムアウトを文字通り実装することは不可能であることを考えると、どのようなソリューションで十分でしょうか?

タイムアウト後に応答に値がない場合、クライアントは単に接続を閉じることができます。これにより、応答が無視されますが、応答が妨げられることはありません。

HTTP要求が送信されるTCP接続を閉じると、サーバーに通知されます。ただし、この通知は遅延して到着するだけなので、遅すぎる可能性があります。また、クライアントソケットが閉じている場合、Webフレームワークは何も実行していない可能性があります。その場合、閉じたソケットに書き込もうとすると、「ピアによって接続がリセットされました」というエラーが発生します。

応答の処理に1秒以上費やしたくない場合は、そのタイムアウトの実装は完全にユーザーの責任であり、ネットワークやHTTPとは関係ありません。

サーバーにタイムアウトを提供するようにクライアントに要求できます。これにより、サーバーが期限に間に合わない場合はサーバーを中止できます。これは、カスタムヘッダーとして、またはURLのクエリパラメーターとして指定できます。この期限は期間ではなく絶対的な時間である必要があります。これにより、送信の遅延も利用可能な時間を消費します。ただし、1秒未満の精度は困難です。サーバーとクライアントを正しい時刻に同期させ、適切なクロックを使用する必要があります。セットアップによっては、正しく構成されている場合でも、ソースが毎回100msオフになる場合があります。これは、時間の予算のかなりの部分をすでに消費しています。


もちろん、タイムアウトを相対時間として送信できます。これは、リクエストを送信してからx秒後にサーバーが処理を停止できないことを意味しますが、サーバーがそれを受信して​​からx秒しかありません。クロックとサーバーのクロックが同じであることを保証できない場合は、より良い場合があります。それらが2分間隔である場合、(絶対時間で)1分のタイムアウトを持つすべての要求が拒否される可能性があります。
gnasher729 2018

1

彼らは接続を閉じることができると思いますが、それによって実際にコードが異常終了するかどうかはわかりません。コードの記述方法によって異なります。

彼らはまた、「時間がかかりすぎるので気にしないでください」という意味の別のメッセージを送信することもできますが、その場合は、おそらく明示的なCANCEL_REQUESTメッセージを処理する準備が整っているはずです。


閉じたポートに書き込むと信号が送られると思いますが、もちろんその信号を無視または処理できます(これはクライアント側からしかわかりません。処理しないと、この問題によりクライアントがクラッシュします)。それとは別に、クライアントはサーバーに何かを強制することはできません。もちろん、サーバーは、ポートが閉じている場合は自発的に作業を中止できます。タイムアウト内に完了しない場合は作業を中止できます。クライアントが要求をキャンセルするメッセージを送信した場合は作業を中止できます。
gnasher729 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.