context設計レビュー完全ガイド:伝播・タイムアウト・責務一致を見抜く

Go言語の context.Context は単なる引数ではなく、設計構造における制御信号の媒体である。
キャンセル・タイムアウト・責務境界を反映するため、レビューアーには構造読解力が強く求められる領域だ。

context.Contextとは

Goの標準ライブラリが提供する制御コンテキスト。
キャンセル通知・タイムアウト制御・要求スコープ共有を実現し、リクエスト起点の統制設計に必須の構造部品となっている。

本記事ではレビューアー視点に徹して、context設計の実務的読解法を徹底解説する。


1. context責務レビュー:何のためのcontextか?

func Handle(ctx context.Context) {
  go func() {
    time.Sleep(5 * time.Second)
    fmt.Println("done")
  }()
}
@Reviewer
contextは受け取っているものの、goroutine内に渡されておらずキャンセル制御が機能していません。非同期処理にも必ず伝播してください。
  • contextは伝播されて初めて機能する
  • 「使っていないcontext」はレビュー上の警告信号

2. context生成責務レビュー:起点・経路が正しいか?

func DoSomething() {
  ctx := context.Background() // 不適切
  callAPI(ctx)
}
@Reviewer
`Background()`で安易に新規生成していますが、本来は上位層のcontextを受け継ぐべきです。親のキャンセル統制を切断する構造になっています。
  • 生成箇所と使用箇所が論理的に接続しているか?
  • 背景生成乱用は伝播断絶の危険設計

3. cancel漏れレビュー:リソースリークを防げ

ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
// defer cancel() がない
@Reviewer
cancel未呼び出しにより、contextツリーがGCまで残存し続けます。`defer cancel()`を確実に記述してください。
  • WithTimeout()WithCancel()使用時は必ずcancel呼び出しが対となる

4. タイムアウト値設計レビュー:定数埋め込みは危険

ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
@Reviewer
timeout秒数がハードコーディングされています。運用変更時の柔軟性が失われるため、設定値や引数化を検討してください。
  • 固定秒数直書きは実務運用で破綻を招きやすい

5. context未伝播レビュー:伝播断絶の危険性

func Do(ctx context.Context) {
  callSub() // ctx未伝播
}

func callSub() {
  // context不使用
}
@Reviewer
上位でキャンセルが発生しても`callSub`側に反映されません。最低限全関数間でcontextは伝播統一してください。
  • 途中でcontextを渡さない設計は断絶構造

6. select設計レビュー:キャンセル検知分岐があるか?

select {
case <-time.After(5 * time.Second):
  // wait
}
@Reviewer
`ctx.Done()`によるキャンセル検知が欠如しています。goroutine停止信号を確実に拾うため、以下改善例のように分岐を整理してください。

改善例

select {
case <-ctx.Done():
  return ctx.Err()
case <-time.After(5 * time.Second):
  // continue
}

7. 誤用パターン一覧と補正例

誤用パターン 問題内容 補正指針
Background乱用 伝播断絶 上位context利用
cancel漏れ リーク発生 defer cancel()徹底
伝播不足 部分層だけ未使用 全層統一伝播
タイムアウト定数埋込 柔軟性消失 設定注入構造化
非同期渡し忘れ 終了制御不能 goroutine渡し必須

8. context層責務レビュー:レイヤー間整合性を確認

  • インフラ層(APIハンドラ)
    • context起点生成(requestスコープ)
  • サービス層
    • 伝播中継・整合維持
  • ドメイン層・処理層
    • select内キャンセル検知・実処理停止制御

各層で「どの粒度のスコープ責任を持つのか」をレビューで常に読み取ることが必要。


9. チェックリスト:contextレビュー集中項目

観点 確認内容
生成起点整合 Background新規乱用有無
cancel呼び出し defer忘れ有無
全層伝播統一 全経路でctx渡し統一
select内検知 Done()監視分岐実装
timeout設計柔軟性 設定注入or外部化
非同期渡し漏れ goroutine内ctx有無

10. UMLで見るcontext伝播モデル

UML Diagram

11. 総括:contextレビューは設計の責務連鎖読解力

contextレビューの本質は「コードを読む」のではなく「設計の信号伝達経路を読む」ことにある。

  • contextは統制責務のスコープ表現
  • contextは終了制御の生死線
  • contextは設計意図が透ける構造の鏡

レビューアーは常に「どの層が誰に支配され、何を制御しているのか」を構造読解できる力を養う必要がある。