Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.
簡単に訳すと、こんな感じ
処理の締め切り・キャンセル信号・API 境界やプロセス間を横断する必要のある
リクエストスコープな値を伝達させることができます。
context の定義は以下の通りです
type Context interface { // Deadline 期限を返す Deadline() (deadline time.Time, ok bool)
// Done チャネルを返す。チャネルはキャンセル・期限切れの場合は閉じる Done() <-chan struct{}
// Err Doneが閉じた理由を返す Err() error
// Value Contextに格納した値を返す Value(key interface{}) interface{}}
0 の状態からコンテキストを生成するにはcontext.Backgroud()
を用いる
これは、「キャンセルされない」「deadline を持たない」「共有する値を持たない」状態
上記で初期化した値にcontext.WithCancel()
を渡すことで、
「Done
からキャンセル有無が判断できる context」と「戻り値のコンテキストをキャンセルするための関数」を取得できます
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
例えば、以下のような形で渡すことで動作する
ctx, cancel := context.WithCancel(context.Backgroud())
// cancel() ctx.Done()で得られるチャネルがcloseされるcancel()
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
context.WithDeadline()
は、引数で渡された親 context の設定を引き継いだ上で
Done メソッドチャネルが第二引数で指定した時刻に自動で close される新たな context になる
タイムアウト前にキャンセルを行うたい場合は、cancel()
を呼び出すことでも close できる
// ctxはtime.Now().Add(time.Second)に自動キャンセルされるctx, cancel := context.WithDeadline(context.Backgroud(), time.Now().Add(time.Second))
// 明示的にcancelさせることもできるcancel()
context.WithDeadline()
を使うことで時刻タイムアウトをできましたが、
context.WithTimeout()
を使うことで時間でタイムアウトさせることも可能です
// ~~ 略~~case result, ok := <-gen: if ok { fmt.Println(result) } else{ fmt.Println(result) break }
これにより、gen チャネルの close 処理が行われるようになる
そのため、タイムアウトかどうかを判定するにはgenチャネルからの受信が、 チャネルcloseによるものか否か
を見るだけで判定できる
type Context interface { Deadline() (deadline time.Time, ok bool)}
第二引数の bool を確認することで、その context がタイムアウトに設定されるか判定できる
設定されている場合は、第一引数にタイムアウト時刻が格納される
type Context interface { Err() error}
context の Err メソッドは、context がキャンセルされた時は nil
明示的にキャンセルされた場合は、Canceled エラー
タイムアウトしていた場合は、DeadlineExceeded エラー
func WithValue(parent Context, key, val interface{}) Context
WithValue を使うことで、context に値を加えることができます。
引数 key は key が、val には value を内部に持ちます。
// ctx内部にkeyが"userID", valueが2入るctx = context.WithValue(parentCtx, "userID", 2)