伝播をキャンセルせずに Go コンテキストを複製するにはどうすればよいですか?

Linda Hamilton
リリース: 2024-11-08 14:17:02
オリジナル
568 人が閲覧しました

How to Clone a Go Context Without Cancel Propagation?

キャンセル伝播を行わずに Go コンテキストを複製する方法

Go プログラミング言語では、context.Context が関数間のメタデータとキャンセル信号を伝達します。そしてゴルーチン。ただし、同じ値を保持するが、元のキャンセル ステータスを継承しないコンテキストのコピーを作成することが望ましい場合があります。

使用例:

このシナリオは、HTTP リクエストのコンテキストがクライアントに応答を返した後にキャンセルされた場合に発生しますが、親コンテキストより長く存続する可能性が高い別の goroutine で非同期タスクを実行する必要があります。

解決策:

1.カスタム コンテキスト実装の作成:

Go 1.21 より前では、独自のコンテキストを作成することが 1 つのアプローチでした。キャンセルされないコンテキスト実装:

import (
    "context"
    "time"
)

type noCancel struct {
    ctx context.Context
}

func (c noCancel) Deadline() (time.Time, bool)       { return time.Time{}, false }
func (c noCancel) Done() <-chan struct{}             { return nil }
func (c noCancel) Err() error                        { return nil }
func (c noCancel) Value(key interface{}) interface{} { return c.ctx.Value(key) }
ログイン後にコピー

その後、次のように作成できます。この実装を使用した新しいコンテキスト:

ctxWithoutCancel := WithoutCancel(ctx)
ログイン後にコピー

2. WithoutCancel 関数を使用する (Go 1.21 ):

Go 1.21 では、コンテキスト パッケージには、このプロセスを簡素化する WithoutCancel 関数が含まれています:

ctxWithoutCancel := context.WithoutCancel(ctx)
ログイン後にコピー

この関数は、次の新しいコンテキストを返します。元のコンテキストと同じ値を共有しますが、キャンセルの対象にはなりません。

例:

func Handler(ctx context.Context) (interface{}, error) {
    result := doStuff(ctx)
    newContext := context.WithoutCancel(ctx)
    go func() {
        doSomethingElse(newContext)
    }()
    return result
}
ログイン後にコピー

この方法では、リクエスト コンテキストの後でも doSomethingElse は実行を継続します。キャンセルされました。

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

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート