- コンテキストとは
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.WithCancel(parent Context) (ctx Context, cancel CancelFunc)
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つのコンテキスト関連のメソッドが付随している
Context() context.Context
WithContext(ctx context.Context ) * Request