💨

GoのContextってなに?

2023/12/16に公開

Go言語の "context" パッケージは、APIの境界やプロセス間でのデータの伝搬とキャンセルシグナル、タイムアウト、デッドラインなどを扱うための機能を提供します。このパッケージは、特にHTTPサーバー、クライアントライブラリ、データベースアクセスなどの分散システムや長時間実行されるプロセスで重要です。

主な機能

  1. キャンセル伝搬: context.Context を介して、複数のゴルーチン間でキャンセルシグナルを伝搬させることができます。これにより、一つの操作がキャンセルされた場合、それに関連する全ての操作も適切にキャンセルされます。

  2. タイムアウトとデッドライン: タイムアウトやデッドラインを設定して、特定の時間を超える操作を自動的にキャンセルできます。これは、リソースの浪費を防ぎ、システムの応答性を高めるのに役立ちます。

  3. 値の伝搬: context.Context は、プロセス全体で共有される値(例えば、リクエストIDや認証情報など)を保持することができます。これにより、これらの値をゴルーチン間で簡単に伝搬できます。

使用例

  • HTTPサーバー: HTTPリクエスト処理中に context.Context を使用すると、リクエストに関連する全てのゴルーチンを管理しやすくなります。例えば、リクエストが一定時間内に完了しない場合、タイムアウトを設定して自動的にこれらのゴルーチンをキャンセルできます。

  • データベースアクセス: データベースクエリの実行時に context.Context を使用すると、クエリのタイムアウトやキャンセルを簡単に管理できます。

重要なポイント

  • 使い始め: 通常、コンテキストは context.Background() または context.TODO() を使って作成されます。context.Background() は、メイン関数や初期化ロジックでの使用が一般的です。

  • 伝搬: コンテキストは、プロセスやAPIの境界を超えて伝搬されます。通常、コンテキストは関数の最初の引数として渡されます。

  • イミュータブル: コンテキストはイミュータブルです。つまり、一度作成されると変更できません。新しい値やキャンセルシグナルを追加する場合は、新しいコンテキストを作成する必要があります。

めちゃくちゃわかりやすく乱暴に言うと

  • Reactでの例え: ReactでいうところのuseContextみたいにグローバルに値を共有したい!でもReactみたいに書けないから、共有したいところに引数としてcontext渡しまくる!!!

Discussion