キャンセル伝播を行わずに 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 サイトの他の関連記事を参照してください。