この記事のポイント

  • timeout設計の安定性責任をレビュー視点で読み解ける
  • 設計臭の典型パターンを実務観点で整理できる
  • 安定運用に耐えるtimeout文化を体系化できる
  • PlantUMLで依存構造とtimeout責務境界を可視化整理できる

そもそもtimeoutとは

timeout(タイムアウト)は「一定時間応答が無い場合に処理を打ち切る仕組み」です。
Pythonでは様々なライブラリ・I/O・通信・DB操作でtimeout設計が発生します。

  • 通信(requests, socket)
  • データベース(connect timeout, read timeout)
  • ファイルI/O(ロック系処理)
  • 並列処理(ThreadPoolExecutor, futures)
requestsのtimeout例

import requests

response = requests.get(
    "https://api.example.com/data", 
    timeout=(5, 10)
)
  • connect timeout:接続待機
  • read timeout:応答待機

なぜこれをレビューするのか

timeout設計は「安定性と可用性の責任境界」です。
レビューアーは以下の設計責務を観察する必要があります。

レビューアー視点

  • timeout値が妥当な見積になっているか
  • 対象責務(通信/DB/外部API等)毎に整理されているか
  • リトライ設計と組み合わせて調整されているか
  • timeout発生後の例外設計が整理されているか
  • SLA(サービスレベル契約)に即した安定性になっているか

開発者視点

  • timeout値を「なんとなく」で決めがち
  • デフォルト(無制限)のまま運用開始しがち
  • リトライ・監視系との組合せを後回し
  • timeout発生時の例外設計が甘くなる
  • レイヤー横断的な一貫性を軽視

timeout設計崩壊の典型設計臭

崩壊しやすいパターン
  • timeout未指定 → 無限待機化
  • 各層でバラバラのtimeout値
  • timeout例外が握り潰される
  • リトライ不在で単発障害に脆弱
  • SLA無視の長短不一致

崩壊例:未指定無限待機型

timeout未指定例

response = requests.get("https://api.example.com/data")
data = response.json()
@Reviewer
timeoutが未指定です。無限待機リスクが発生します。明示指定を必須化してください。

問題点

  • API応答停止 → 永久ブロック
  • スレッド・接続枯渇

崩壊構造モデル:無限待機型

UML Diagram

timeout安定性整理の設計原則

以下の安定性責任文化が健全性維持に有効です。

① timeout強制指定文化

  • timeoutは全通信で常時明示化

② SLA準拠文化

  • timeout値はサービス設計契約から逆算

③ リトライ組合せ文化

  • 短timeout × 複数リトライで安定性最適化

④ 責務別整理文化

対象層 timeout目安
通信系API connect=3s, read=5s
DB接続 connect=3s, query=10s
内部処理 lock=30s

⑤ 例外設計文化

  • timeout例外を原因別捕捉整理

改善例:責務分離設計版

改善設計版

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

class ApiClient:
    BASE_URL = "https://api.example.com"

    def __init__(self):
        self.session = requests.Session()
        retries = Retry(total=3, backoff_factor=1, status_forcelist=[502, 503, 504])
        self.session.mount("https://", HTTPAdapter(max_retries=retries))

    def fetch_data(self):
        try:
            response = self.session.get(
                f"{self.BASE_URL}/data",
                timeout=(3, 5)
            )
            return response.json()
        except requests.exceptions.Timeout:
            self.handle_timeout()
        except requests.exceptions.RequestException as e:
            self.handle_general_error(e)

    def handle_timeout(self):
        logger.error("API timeout occurred.")

    def handle_general_error(self, e):
        logger.error(f"API general error: {e}")
「timeout責務分離文化+リトライ組合せ文化」

レビューアーは「timeoutは組合せ設計文化」を徹底確認すると安定性が確保されます。

改善構造モデル:責務整理構造

UML Diagram

良くない実装例: ケース1(全域try-except)

全域例外例

try:
    response = requests.get("https://api.example.com/data", timeout=5)
except Exception as e:
    logger.error(e)
@Reviewer
例外粒度が広域化しています。timeout専用捕捉を整理してください。

問題点

  • 原因別通知困難
  • 運用上の障害判定困難

改善例:粒度分離整理

粒度整理版

try:
    response = requests.get("https://api.example.com/data", timeout=5)
except requests.exceptions.Timeout:
    logger.error("API Timeout")
except requests.exceptions.RequestException as e:
    logger.error(f"API Error: {e}")
  • 障害分類が明確化

良くない実装例: ケース2(各層値不一致)

不一致例

requests.get(..., timeout=3)
DB.connect(timeout=20)
internal_lock(timeout=60)
@Reviewer
timeout値が層毎に不整合です。統一設計指針を定義してください。

問題点

  • 層を跨ぐ安定性設計不統一
  • 責任境界が不透明

改善例:統一指針整理

層別統一整理

API_TIMEOUT_CONNECT = 3
API_TIMEOUT_READ = 5
DB_TIMEOUT = 10
LOCK_TIMEOUT = 30
  • 値を集中定義
  • SLA準拠可能

良くない実装例: ケース3(リトライ文化欠落)

リトライ欠落例

requests.get("https://api.example.com/data", timeout=5)
@Reviewer
リトライ設計が不在です。短timeout×複数リトライ文化を適用してください。

問題点

  • 瞬断耐性消失
  • 一時障害で即障害化

改善例:短timeout×リトライ適用

リトライ適用版

retries = Retry(total=3, backoff_factor=1)
adapter = HTTPAdapter(max_retries=retries)
session = requests.Session()
session.mount("https://", adapter)
session.get("https://api.example.com/data", timeout=(3,5))
  • 安定性設計が実用適応

観点チェックリスト

まとめ

timeout設計は「設計者の安定性責任がもっとも露骨に現れる領域」です。
レビューアーは「timeout強制文化・リトライ文化・SLA準拠文化」を育成指導することで、
障害耐性と可用性の高い実務レベルの安定設計を維持できます。