Python|timeout設計の安定性責任整理法
この記事のポイント
- 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()
@Reviewertimeoutが未指定です。無限待機リスクが発生します。明示指定を必須化してください。
問題点
- API応答停止 → 永久ブロック
- スレッド・接続枯渇
崩壊構造モデル:無限待機型
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は組合せ設計文化」を徹底確認すると安定性が確保されます。
改善構造モデル:責務整理構造
良くない実装例: ケース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)
@Reviewertimeout値が層毎に不整合です。統一設計指針を定義してください。
問題点
- 層を跨ぐ安定性設計不統一
- 責任境界が不透明
改善例:統一指針整理
層別統一整理
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準拠文化」を育成指導することで、
障害耐性と可用性の高い実務レベルの安定設計を維持できます。

