PHP エディター Xinyi が HTTP リクエストを処理するとき、リクエスト コンテキストのキャンセルをリッスンする必要があるかどうかは、一般的な質問です。実際の開発では、PHP 実行環境が関連するリソースの解放作業を自動的に処理するため、通常、リクエスト コンテキストのキャンセルを明示的に監視する必要はありません。ただし、リソースを手動で解放する必要がある場合やクリーンアップ操作を実行する必要がある場合など、一部の特殊な場合には、リクエスト コンテキストのキャンセルをリッスンすることが効果的な方法となる場合があります。したがって、リクエスト コンテキストのキャンセルをリッスンする必要があるかどうかは、特定のビジネス要件と開発シナリオによって異なります。ほとんどの場合、PHP の自動リソース管理メカニズムを安全に信頼できます。
応答を返す前に他の操作を実行する http ハンドラーを作成していると仮定すると、http リクエスト コンテキストがキャンセルされたかどうかを確認するリスナーを設定する必要がありますか?すぐに返せるようにするため、またはリクエストコンテキストがキャンセルされたときにハンドラーを終了する他の方法はありますか?
リーリー テストしようとしましたが、コンテキストがキャンセルされた後も、dosomething
関数は停止せず、バックグラウンドで実行されたままです。
func handlesomething(w http.responsewriter, r *http.request) { done := make(chan error) go func() { if err := dosomething(r.context()); err != nil { done <- err return } done <- nil }() select { case <-r.context().done(): http.error(w, r.context().err().error(), http.statusinternalservererror) return case err := <-done: if err != nil { http.error(w, err.error(), http.statusinternalservererror) return } w.writeheader(http.statusok) w.write([]byte("ok")) } } func dosomething(ctx context.context) error { // simulate doing something for 1 second. time.sleep(time.second) return nil }
提供されたソリューションを少しリファクタリングしただけで、現在は機能するはずです。変更点についてご案内させていただきます。
何かをする
関数キャンセル入力を待つか、3
秒の遅延後に呼び出し元に戻ります。リッスンするコンテキストを受け入れます。
ハンドル何か
関数ここでのロジックはあなたのものと非常によく似ています。選択では、受信したエラーが nil
であるかどうかを確認し、それに応じて呼び出し元に正しい http ステータス コードを返します。キャンセル入力を受け取った場合は、すべてのコンテキスト チェーンをキャンセルします。
testhandler
関数ここでは、http サーバーを起動し、http.client
経由で http リクエストを送信します。コンテキスト タイムアウトを設定するステートメントが 2 つあることがわかります。コメント // request cancels
を含むものを使用すると、すべてがキャンセルされます。それ以外の場合、別のものを使用すると、リクエストが処理されます。
これであなたの質問が明確になることを願っています。
以上がhttp ハンドラーを作成するとき、リクエスト コンテキストのキャンセルをリッスンする必要がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。