ホームページ  >  記事  >  バックエンド開発  >  http ハンドラーを作成するとき、リクエスト コンテキストのキャンセルをリッスンする必要がありますか?

http ハンドラーを作成するとき、リクエスト コンテキストのキャンセルをリッスンする必要がありますか?

WBOY
WBOY転載
2024-02-08 23:03:281151ブラウズ

http ハンドラーを作成するとき、リクエスト コンテキストのキャンセルをリッスンする必要がありますか?

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 サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。