ホームページ  >  記事  >  バックエンド開発  >  キャンセル伝播を行わずに Go でコンテキストを使用するにはどうすればよいですか?

キャンセル伝播を行わずに Go でコンテキストを使用するにはどうすればよいですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-08 20:57:021005ブラウズ

How Can I Use Contexts in Go Without Cancellation Propagation?

キャンセル伝播のないコンテキスト: 詳細

Go のコンテキストは、リクエストとともに任意の値を渡し、キャンセルを追跡するメカニズムを提供します。デフォルトでは、すべてのコンテキストが同じキャンセルメカニズムを共有します。ただし、特定のシナリオでは、コンテキストの伝播をキャンセルから切り離す必要がある場合があります。

キャンセルしないコンテキストの必要性

リクエストの存続期間を超えてタスクを実行する HTTP ハンドラーを検討してください。応答を返した後、ハンドラーはゴルーチンで非同期タスクを開始できます。このタスクはコンテキスト値へのアクセスを必要とする場合がありますが、元のリクエスト コンテキストがキャンセルされた場合は終了しないでください。

カスタム非キャンセル コンテキストの作成

WithoutCancel は Go 1.21 で導入され、簡単な方法を提供しました。非キャンセルコンテキストを作成します。このメソッドを使用すると、保存されているすべての値を含む元のコンテキストのコピーを取得できますが、キャンセル ステータスには依存しません。

非キャンセル コンテキストの実装

Go 1.21 より前では、カスタム非キャンセルコンテキストの実装が必要でした。重要なのは、context.Context インターフェイスを満たす型を作成し、キャンセルを防ぐために次のメソッドをオーバーライドすることです。

  • Deadline(): 常にゼロを返し、2 番目の戻り値を false に設定します。
  • Done(): nil チャネルを返し、キャンセルが不可能であることを示します。
  • Err(): 常に nil を返し、エラーが発生していないことを示します。

さらに、実装は元のコンテキストを保存し、保存された値を取得するために Value() 呼び出しを委任する必要があります。

非キャンセルコンテキストの使用例

import (
    "context"

    "github.com/mypackage/mycontext"
)

func Handler(ctx context.Context) (interface{}, error) {
    result := doStuff(ctx)
    newContext := mycontext.WithoutCancel(ctx)
    go func() {
        doSomethingElse(newContext)
    }()
    return result
}

結論

非キャンセルコンテキストの背後にある原則を理解し、利用可能なツールを活用することで、開発者はカスタムソリューションを作成したり、Go の組み込み機能を利用して、キャンセルなしで目的のコンテキスト伝播を実現したりできます。

以上がキャンセル伝播を行わずに Go でコンテキストを使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。