制御可能性中心設計(Controllability-Centered Design)シリーズ
前回:安定性から制御可能性へ:システムを破綻から救う新たな設計基準 (第2回)
今回:外部API依存環境における自己修復型データ基盤の階層設計 (第3回)
次回:破壊を前提としたColab×SQLiteの物理再構成アーキテクチャ (第4回)
...(全8回・完結)
1. 問題設定
外部APIやネットワークストレージに依存するシステム(一例としての定期実行スクリーナー等)において、システム全体の信頼性は単一のリカバリロジックや例外処理によって横断的に担保可能であると仮定されることが多い。
しかし、本設計ではこの仮定を採用しない。外部起因の不確実性は単一の層で処理できるものではなく、複数の次元にまたがって発生するからである。
2. 観測された問題群
ネットワーク越しの外部リソースを活用する継続的な運用環境において、以下の明確な不具合および不整合が観測された。
- 通信断: 外部API呼び出し時における HTTP 429 Too Many Requests やタイムアウトに伴うプロセスの強制停止
-
DB破損: ネットワークファイルシステム(Google Drive等)越しの SQLite 接続において、不整合なロックが残留し
OperationalErrorが恒常的に発生する事象 -
データ欠損: 取得した JSON およびオブジェクト内において、期待されるキーに対する
NoneやNaNの予測不規則な出現 - 恒等式違反: 財務指標において「売上 − 原価 ≠ 営業利益」や「資産 ≠ 負債 + 純資産」となるような、構造的かつ論理的な不整合
3. 単一対策が不十分な理由
客観的に観測された上記の問題群に対し、単一のコードブロックで例外捕捉(Try-Catch)を行うような平面的対策では十分な耐性を確保できない。物理的な I/O 破損と、ドメイン空間での論理的なデータ欠損や恒等式違反は、発生の起因も影響を及ぼすスコープも全く異なる次元の問題である。
これらを混同して単一のレイヤーで解決を試みる設計は、システム内部の結合度を不必要に高める。結果として、局所的なエラーが全体の論理不整合を招き、システム構造の連鎖的な破綻を引き起こす。問題が明確に層(レイヤー)を跨ぐ構造であることを認識し、分離して処理するアプローチが必要である。
4. レイヤー構造の再定義
ここで、システム全体の回復力と整合性を担保するため、不確実性への対応責務を階層(レイヤー)として分割・再定義する。各レイヤーは自身が担当する境界内の例外を吸収し、上位レイヤーに対しては決定論的な環境を提供する。
本構成は以下の4レイヤーで定義している。
各レイヤーの責務は以下の通り定義する。
-
Layer 1: 物理耐性(SQLite自己修復)
ファイルシステムの異常を前提とし、壊れた対象ファイルの物理削除と初期化によって稼働基盤を強制的に再構築する -
Layer 2: API耐性(リトライ・キャッシュ制御)
外部通信のネットワーク不安定性を前提とし、ジッター付きリクエストとローカルキャッシュを用いてシステム境界を保護する -
Layer 3: 状態決定(ハッシュベース更新判定)
状態の変化が存在しない対象に対する無意味かつ高コストなAPIリクエストの反復を防ぐ。状態同一性の評価をハッシュシグネチャに委譲し、状態が変容した対象のみを処理へルーティングする -
Layer 4: 恒等式再構成(整合性基準)
論理的なデータ欠損や恒等式違反を例外ではなく再構成対象とし、財務上の制約や恒等式を用いて該当数値を算出・復元する
5. 既存記事との対応関係
本アーキテクチャを構成する各階層の具体的な実装要件および設計判断の詳細は、以下の各記事にて独立して定義している。
- Layer 1対応: 『破壊を前提としたColab×SQLiteの物理再構成アーキテクチャ』(実践編: 『Google Colab × SQLite3 を「壊れる前提」で安定運用する方法(自己修復20行+AIキャッシュ戦略)』)
- Layer 2対応: 『yfinanceの限界とAPI境界の構造的安定化設計』
- Layer 3対応: 『AI消費を9割削る、状態決定とハッシュキャッシュの自律設計』
- Layer 4対応: 『yfinanceと日本株:データ欠損を恒等式で自律再構成する整合性基準設計』(実践編: 『Python + yfinance で日本株分析:データ欠損・429エラーを「自己修復」して止まらないスクリーナーを作る』)
6. 設計原則の整理
自律稼働と安定化を目的として構築された本アーキテクチャは、最終的に以下の設計原則のもとに運用されている。
- 外部入力は未検証データ: 自システムの制御外から流入するデータは如何なる型・値であっても信用せず、境界において評価・隔離を行う
- 一致ではなく整合性を守る: 取得した単一の値が存在すること(一致)を保証するのではなく、系全体を構成する要素間の恒等式が成立していること(整合性)を基準とする
- 各層は独立して破綻に耐える: 下位レイヤーにおける物理的・通信的な破壊は、上位レイヤーの論理状態に波及する前に完全に捕捉・遮断される
- 状態は決定論的に管理する: バイト列の厳密なハッシュ関数によってのみ状態の同一性を決定し、振る舞いを制御する
本稿は、現時点で実装および運用している構成の事実の整理である。各レイヤーが独立して破綻に耐える構造を持つことにより、実運用環境においてエラー起因によるシステムの連鎖停止は発生していない。同時に、本構成は進化可能な前提で設計しており、運用ドメインの拡大に伴う将来的なレイヤーの追加や、各階層における責務の再定義の可能性を包含している。