• コンテキストとはcontextパッケージで次のように定義されたContextインタフェースを満たすインスタンスのこと
type Context interface {
	Deadline() (deadline time.Time, ok bool)
	Done() <-chan struct{}
	Err() error
	Value(key any) any
}
  • 「関数からの最後の戻り値はerrorである」というGoの慣習があるが、「コンテキストは関数の最初の引数ctxとして明示的に渡す」という慣習もある

14.1.1 コンテキストのファクトリ関数

  • contextパッケージには、コンテキストを生成したりラップするための次のようなファクトリ関数も準備されている
    • アプリケーションのエントリーポイントで用いる関数
      • context.Background()
    • キャンセルやタイムアウトを管理したい場合に用いる関数
      • context.WithCancel(parent Context) (ctx Context, cancel CancelFunc)
        • 親コンテキストにキャンセル機能を追加した新しいコンテキストを生成する。cancel関数を呼び出すことで、全ての子コンテキストをキャンセルできる
        • https://pkg.go.dev/context#WithCancel
      • context.WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
      • context.WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
    • 特定のリクエストやゴルーチン間で値を伝播したい場合に用いる関数
      • context.WithValue(parent Context, key, val any) Context
    • 開発期間中のデバッグに用いる関数
    • context.TODO() Context
    • 空の親コンテキストを返す。コンテキストがどこから来ているか、どのように使われているか不明な場合に使用する
  • 空のコンテキストが出発点になり、コンテキストにメタデータを追加していく。メタデータの追加はファクトリ関数を使用して既存のコンテキストをラップすることで行う

14.1.2 HTTPサーバーのコンテキストの特殊事情

  • HTTPサーバーのコンテキスト受け渡しは上記とは異なるパターンを使う
    • net/httpが作成されて、かなり後にコンテキストが追加された為。後方互換性を保つために、http.Handlerインタフェースを変更してコンテキストを引数として追加することはできなかった
  • http.Request構造体には次の2つのコンテキスト関連のメソッドが付随している