10
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

Goの障害対応でよくあるのが

  • 外部APIが詰まる
  • goroutineが溜まる
  • タイムアウトしない
  • 復旧してもプロセスが重いまま

というパターンです。

原因はだいたい

  • context を受け取っていない
  • context を渡していない
  • タイムアウトの責務が曖昧

のどれかです。

この記事は context の仕様説明ではなく
実務で事故らないための設計チェックリストとしてまとめます。

まず決める前提

  • タイムアウトは誰が決めるか(入口か呼び出し先か)
  • キャンセルはどこまで伝播させるか
  • 何をログに残すか(期限超過か、キャンセルか)

よくある失敗パターン

背景で勝手に動き続ける

HTTPリクエストが切れても処理が残り

  • DB
  • 外部API
  • キュー

が詰まります。

context.Background を深いところで使う

一見動きますが

  • タイムアウトが効かない
  • トレースが途切れる

ので、障害時に最悪です。

WithTimeout の多重化

あちこちで勝手にタイムアウトを付けると

  • どれが効いたのか分からない
  • 期限が短すぎて落ちる

になります。

設計の型

境界で受け取る

  • HTTPハンドラ
  • gRPC
  • ジョブキュー

の入口で ctx を受け取ります。

境界で締める

タイムアウトは

  • 入口でまとめて付ける

のが基本です。

内部で付けるのは

  • 個別I/Oだけ短くしたい

など理由があるときに限定します。

下層へ渡す

  • DB
  • 外部API
  • 依存サービス

に必ず ctx を渡します。

チェックリスト(レビュー用)

  • 境界で ctx を受け取っている
  • 関数引数に ctx があるのに捨てていない
  • context.Background を深い層で使っていない
  • WithTimeout の責務が曖昧になっていない
  • cancel を必ず呼んでいる(defer cancel)
  • 期限超過とキャンセルをログで区別できる

まとめ

context はGoの並行処理の安全装置です。

  • 境界で受け取る
  • 境界で締める
  • 下層へ渡す

この型を守るだけで、タイムアウト事故とgoroutineリークが激減します。

10
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?