見出し画像

Goのコンテキスト管理: context.Canceled と context.DeadlineExceededについて

はじめに

■GoのContextとは

GoパッケージにはContextパッケージが実装されています。このパッケージでは、異なるAPIやプロセスを超えて通信の期限(deadline)やキャンセル信号を伝達するContextタイプを定義しています。

■Contextに定義されている変数について

Contextパッケージには以下の2つの変数が定義されています。

  • Canceled

  • DeadlineExceed 

context.Canceledについて

■概要

context.Canceledはコンテキストがキャンセルされた場合に返されるエラーです。

■具体例

例えば、クライアント側から通信がキャンセルされた時に発生することがあります。重いWebページを読んでいるときに、読み込み中にブラウザの「×」ボタンを押して通信をキャンセルした際に、サーバーにそれが伝達され エラーとしてcontext.Canceledが返却されます。

context.DeadlineExceededについて

■概要

context.DealineExceededは設定されたタイムアウトが経過した場合に返されるエラーです。

■具体例

例えば、context.WithTimeout関数で設定したタイムアウトを超えて通信を実施しようとしたときに発生します。例えば以下は5秒以上通信に時間がかかった場合、通信をキャンセルしctx.Err()がDeadlineExceeded を返却します

ctx, cancel := context.WithTimeout(r.Context(), 5 * time.Second)

以下は2種類のエラーを判別するコードスニペットです。

// 5秒をタイムアウトとする
ctx, cancel := context.WithTimeout(r.Context(), 5 * time.Second)
defer cancel()

select {
... 
case <-ctx.Done():
    switch ctx.Err() {
    case context.Canceled:
        // クライアント側からキャンセルされた場合
    case context.DeadlineExceeded:
        // タイムアウトが発生した場合
    default:
        // その他のエラー
    }
}