【要約】同じバグを3回直した — 「経路ごとに塞ぐ」のをやめて不変条件で書き直すまで [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
開発者が、暗号資産自動売買BOTの再起動時にジョブが「dead」と判定される問題に直面した。再起動のたびに古い実行時刻が残り、判定ロジックが初回ジョブの起動に先行してしまう。
- ・再起動時に古い
last_run_atがDBに残る。 - ・起動猶予(900秒)と実行間隔(900秒)が同値で、判定が初回実行に先行する。
- ・修正が特定のコードパスに限定され、新たな起動経路が増えるたびにバグが再発する。
// Approach
開発者は、個別の修正経路を塞ぐのではなく、判定ロジックの根幹を書き換える手法を採用した。実装の詳細に依存せず、システムとして成立し得ない状態を排除する設計を行った。
- ・「プロセス起動時刻より前の時刻は応答なしの起点になり得ない」という不変条件を定義。
- ・
last_run = max(last_run, _engine_start_time)を導入し、判定の起点を制御。 - ・DBの値を書き換えるのではなく、判定ロジック側のみで完結させる。
// Result
この設計変更により、再起動に伴う競合問題が根本的に解決された。修正の対象を「状態の書き換え」から「判定の定義」へ移したことで、堅牢性が向上している。
- ・新しい起動経路が増えても、修正なしで動作を維持できる。
- ・DBへの書き込みを回避し、他の処理との競合リスクを低減。
- ・回帰テストにより、境界条件での正常動作を実証。
Senior Engineer Insight
> 「経路を塞ぐ」修正は、システムの複雑性が増すほど限界を迎える。これは典型的なパッチ当てであり、技術負債を蓄積させる。不変条件に基づいた設計は、実装の詳細に依存せず整合性を保証する。大規模・高可用性システムでは、この「原理へのアプローチ」が不可欠である。場当たり的な数値調整(猶予時間の延長など)は、単なる問題の先送りであることを肝に銘じるべきだ。