Go言語の Context パッケージ徹底解説
Go 言語の context
パッケージは、ゴルーチン間でのキャンセル、タイムアウト、デッドライン、および値の共有を管理するための仕組みを提供します。本記事では、context
パッケージの基本概念から具体的な使用方法まで詳しく解説します。
1. Context とは?
context
は、Go 言語において非同期処理やネットワークリクエストの制御を容易にするための仕組みです。具体的には、以下の機能を提供します。
- キャンセルの伝播: 特定の処理を中断するための仕組み
- タイムアウト制御: 一定時間が経過したら処理を強制終了
- デッドライン設定: 期限を指定して処理を中止
- 値の受け渡し: ゴルーチン間でのデータ共有
Go の標準ライブラリの多くは context
をサポートしており、HTTP リクエストやデータベースアクセスなどの処理を適切に管理できます。
2. context
パッケージの基本的な使い方
context
パッケージには、複数の関数が用意されており、それぞれ異なる用途で使用されます。
2.1 context.Background()
の利用
context.Background()
は、親となるコンテキストがない場合に使用される基本的なコンテキストです。
package main
import (
"context"
"fmt"
)
func main() {
ctx := context.Background()
fmt.Println(ctx)
}
2.2 context.WithCancel()
でキャンセル処理
WithCancel
を使うことで、キャンセルが可能なコンテキストを生成できます。
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // 必ずキャンセルを呼び出す
go func() {
time.Sleep(2 * time.Second)
cancel()
}()
<-ctx.Done()
fmt.Println("Context canceled")
}
2.3 context.WithTimeout()
でタイムアウト設定
一定時間後にキャンセルされるコンテキストを作成するには context.WithTimeout()
を使用します。
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
select {
case <-ctx.Done():
fmt.Println("Timeout exceeded")
}
}
2.4 context.WithDeadline()
でデッドライン設定
特定の時刻をデッドラインとして設定する場合は context.WithDeadline()
を使用します。
package main
import (
"context"
"fmt"
"time"
)
func main() {
deadline := time.Now().Add(3 * time.Second)
ctx, cancel := context.WithDeadline(context.Background(), deadline)
defer cancel()
select {
case <-ctx.Done():
fmt.Println("Deadline reached:", ctx.Err())
}
}
2.5 context.WithValue()
で値を共有
context.WithValue()
を使うと、コンテキスト内に値を保存してゴルーチン間で共有できます。
package main
import (
"context"
"fmt"
)
func main() {
ctx := context.WithValue(context.Background(), "userID", 42)
fmt.Println("User ID:", ctx.Value("userID"))
}
ただし、大きなデータを context
に格納するのは推奨されていません。データ共有には context
ではなく、チャネルや構造体を利用するのが適切です。
3. context
を使うべき場面
context
は以下のようなケースで特に有効です。
- HTTP リクエストのタイムアウト管理
- データベースクエリのキャンセル処理
- 長時間実行される処理の制御
- 複数のゴルーチン間での情報共有
まとめ
Go 言語の context
パッケージを活用することで、非同期処理やゴルーチンの適切な管理が可能になります。特に、
-
context.Background()
は基本となるコンテキスト -
context.WithCancel()
でキャンセル可能なコンテキストを作成 -
context.WithTimeout()
で一定時間後にキャンセル -
context.WithDeadline()
で特定の時刻にキャンセル -
context.WithValue()
で値をゴルーチン間で共有
といった機能を理解し、適切に活用しましょう。