docs: Phase 9.75 Box設計根本革命 - SocketBox Arc<Mutex>責務一元化
✅ Phase 9.75実装計画追加: - copilot_issues.txtにPhase 9.75追加(Phase 9.7と9.8の間) - Arc<Mutex>二重化問題の根本解決計画 - 段階的実装戦略(Phase A-D)定義 📚 Box設計ドキュメント完全体系化: - docs/説明書/reference/box-design/ 新設 - everything-is-box.md: 核心哲学の完全解説 - memory-management.md: Arc<Mutex>設計・fini/weak参照 - delegation-system.md: 完全明示デリゲーション仕様 - box-types-catalog.md: 全Box型の完全カタログ - ffi-abi-specification.md: FFI/ABI仕様(移動済み) 🔧 実装ノート完備: - current-issues.md: 現在進行中の設計課題 - socket-box-problem.md: Arc<Mutex>二重化問題詳細分析 - phase-9-75-redesign.md: 実装計画詳細 👥 Copilot実装ガイド作成: - phase9_75_socketbox_arc_mutex_redesign.md - SocketBox優先対応の具体的実装手順 - 完全テストスイート設計 - 段階的実装戦略(Step 1-5) 📋 CURRENT_TASK.md更新: - Box設計ドキュメント完成記録 - Phase 9.75準備完了状況 🎯 効果: - Everything is Box哲学の体系的文書化 - SocketBox問題解決の明確な道筋 - Copilot協調実装の準備完了 - 新規開発者オンボーディング改善 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,117 @@
|
||||
# 🔧 Box設計の現在の課題
|
||||
|
||||
## 📅 最終更新: 2025-08-14
|
||||
|
||||
このドキュメントは、Nyash Box設計における現在進行中の技術的課題と対応状況をまとめています。
|
||||
|
||||
## 🚨 Critical: Arc<Mutex>責務の二重化問題
|
||||
|
||||
### 問題の概要
|
||||
現在、15個のBox型において、内部と外部で二重にロック管理が行われています。
|
||||
|
||||
```rust
|
||||
// 🚨 現在の問題構造
|
||||
pub struct SocketBox {
|
||||
listener: Arc<Mutex<Option<TcpListener>>>, // 内部ロック
|
||||
is_server: Arc<Mutex<bool>>, // 内部ロック
|
||||
}
|
||||
|
||||
// インタープリター側
|
||||
Arc<Mutex<SocketBox>> // 外部ロック
|
||||
|
||||
// 結果: 二重ロック → デッドロック・状態不整合
|
||||
```
|
||||
|
||||
### 影響を受けるBox型(15個)
|
||||
1. **ネットワーク系**: SocketBox, HTTPServerBox
|
||||
2. **コレクション系**: ArrayBox, MapBox, BufferBox
|
||||
3. **I/O系**: FileBox, StreamBox
|
||||
4. **P2P系**: P2PBox, IntentBox, SimpleIntentBox
|
||||
5. **GUI系**: EguiBox
|
||||
6. **特殊系**: RandomBox, DebugBox, FutureBox, JSONBox
|
||||
|
||||
### 根本原因
|
||||
- **責務の混在**: Box自身がスレッドセーフティを管理
|
||||
- **設計の不統一**: 各Box実装者が独自にArc<Mutex>を使用
|
||||
- **ガイドライン不足**: 正しいBox実装パターンが未確立
|
||||
|
||||
### 対応計画
|
||||
**Phase 9.75**として緊急対応中。詳細は[phase-9-75-redesign.md](phase-9-75-redesign.md)参照。
|
||||
|
||||
## ⚠️ High: SocketBox状態保持問題
|
||||
|
||||
### 問題の詳細
|
||||
SocketBoxで`bind()`後に`isServer()`を呼ぶと、状態が保持されていない。
|
||||
|
||||
```nyash
|
||||
// 期待される動作
|
||||
server = new SocketBox()
|
||||
server.bind("127.0.0.1", 8080) // true
|
||||
server.isServer() // true であるべき
|
||||
|
||||
// 実際の動作
|
||||
server.isServer() // false (状態が失われる)
|
||||
```
|
||||
|
||||
### 技術的分析
|
||||
詳細は[socket-box-problem.md](socket-box-problem.md)参照。
|
||||
|
||||
### 暫定対策
|
||||
- PR #75でArc参照共有を試みたが、根本解決には至らず
|
||||
- デッドロック問題は解決したが、状態保持問題は継続
|
||||
|
||||
## 🟡 Medium: Box型の増殖管理
|
||||
|
||||
### 現状
|
||||
- 基本実装済みBox: 20種類以上
|
||||
- 各Boxが独自の実装パターン
|
||||
- 統一的な品質管理が困難
|
||||
|
||||
### 課題
|
||||
1. **実装の一貫性**: 各Boxで異なる実装スタイル
|
||||
2. **テストカバレッジ**: Box間でテスト密度にばらつき
|
||||
3. **ドキュメント**: API仕様の記述レベルが不統一
|
||||
|
||||
### 対応方針
|
||||
- Box実装テンプレートの作成
|
||||
- 自動テスト生成ツールの検討
|
||||
- APIドキュメント自動生成
|
||||
|
||||
## 🟢 Low: パフォーマンス最適化
|
||||
|
||||
### 観測された問題
|
||||
- 二重ロックによるパフォーマンス低下
|
||||
- Box生成時のオーバーヘッド
|
||||
- メソッド呼び出しの動的ディスパッチコスト
|
||||
|
||||
### 最適化の機会
|
||||
1. **ロック削減**: Arc<Mutex>一元化で改善見込み
|
||||
2. **Box生成**: オブジェクトプールの検討
|
||||
3. **メソッド呼び出し**: インライン化・特殊化
|
||||
|
||||
## 📊 課題の優先順位
|
||||
|
||||
1. **🔴 最優先**: Arc<Mutex>責務一元化(Phase 9.75)
|
||||
2. **🟠 高優先**: SocketBox状態保持問題の根本解決
|
||||
3. **🟡 中優先**: Box実装ガイドライン策定
|
||||
4. **🟢 低優先**: パフォーマンス最適化
|
||||
|
||||
## 🔄 進捗追跡
|
||||
|
||||
### 2025-08-14
|
||||
- Phase 9.75として「Box設計根本革命」を`copilot_issues.txt`に追加
|
||||
- Box設計ドキュメントフォルダを新規作成
|
||||
- 現在の課題を体系的に整理
|
||||
|
||||
### 今後の予定
|
||||
- Phase 9.75 Phase A: 設計ガイドライン策定(3日)
|
||||
- Phase 9.75 Phase B: 最優先Box修正(1週間)
|
||||
- Phase 9.75 Phase C: ステートフルBox修正(1週間)
|
||||
- Phase 9.75 Phase D: 残りのBox統一(3日)
|
||||
|
||||
---
|
||||
|
||||
関連ドキュメント:
|
||||
- [Phase 9.75実装計画](phase-9-75-redesign.md)
|
||||
- [SocketBox問題詳細](socket-box-problem.md)
|
||||
- [Box設計原則](../memory-management.md)
|
||||
@ -0,0 +1,231 @@
|
||||
# 🔧 Phase 9.75: Box設計根本革命 - 実装計画詳細
|
||||
|
||||
## 📅 実施期間: 2025-08 (Phase 9.7完了後)
|
||||
|
||||
## 🎯 目標
|
||||
|
||||
Arc<Mutex>責務の二重化問題を根本的に解決し、すべてのBox型で統一的な設計を実現する。
|
||||
|
||||
## 🏗️ 新設計アーキテクチャ
|
||||
|
||||
### Before(現在の問題設計)
|
||||
```rust
|
||||
// Box内部でロック管理
|
||||
pub struct SocketBox {
|
||||
listener: Arc<Mutex<Option<TcpListener>>>,
|
||||
is_server: Arc<Mutex<bool>>,
|
||||
}
|
||||
|
||||
// インタープリターでも二重ロック
|
||||
Arc<Mutex<dyn NyashBox>>
|
||||
```
|
||||
|
||||
### After(新設計)
|
||||
```rust
|
||||
// 純粋なデータコンテナ
|
||||
pub struct SocketBox {
|
||||
listener: Option<TcpListener>,
|
||||
is_server: bool,
|
||||
}
|
||||
|
||||
// インタープリターが一元管理
|
||||
Arc<Mutex<dyn NyashBox>>
|
||||
```
|
||||
|
||||
## 📋 実装フェーズ
|
||||
|
||||
### Phase A: 設計ガイドライン策定(3日)
|
||||
|
||||
#### A-1: Box実装パターンドキュメント
|
||||
```rust
|
||||
// ✅ 推奨パターン
|
||||
pub struct MyBox {
|
||||
base: BoxBase,
|
||||
data: String, // シンプルなフィールド
|
||||
count: usize, // Arc<Mutex>不要
|
||||
items: Vec<Item>, // 直接保持
|
||||
}
|
||||
|
||||
// ❌ アンチパターン
|
||||
pub struct BadBox {
|
||||
data: Arc<Mutex<String>>, // 内部ロック禁止
|
||||
count: Arc<Mutex<usize>>, // 過剰な同期
|
||||
}
|
||||
```
|
||||
|
||||
#### A-2: テンプレート作成
|
||||
- `box_template.rs` - 新Box実装のひな形
|
||||
- `box_test_template.rs` - テストスイートひな形
|
||||
- マクロによる定型処理自動化検討
|
||||
|
||||
#### A-3: 既存コードレビュー
|
||||
- 15個のBox型の実装詳細調査
|
||||
- 問題パターンの分類
|
||||
- 修正難易度の評価
|
||||
|
||||
### Phase B: 最優先Box修正(1週間)
|
||||
|
||||
#### B-1: SocketBox修正
|
||||
```rust
|
||||
// 新実装
|
||||
impl NyashBox for SocketBox {
|
||||
fn bind(&mut self, addr: &str, port: u16) -> Result<(), String> {
|
||||
match TcpListener::bind((addr, port)) {
|
||||
Ok(listener) => {
|
||||
self.listener = Some(listener);
|
||||
self.is_server = true;
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(e.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### B-2: HTTPServerBox修正
|
||||
- SocketBoxと同様のパターンで修正
|
||||
- 内部SocketBoxとの連携確認
|
||||
|
||||
#### B-3: テストスイート作成
|
||||
```nyash
|
||||
// 状態保持テスト
|
||||
test "SocketBox state persistence" {
|
||||
server = new SocketBox()
|
||||
assert(server.bind("127.0.0.1", 8080) == true)
|
||||
assert(server.isServer() == true) // 必ず成功すること
|
||||
}
|
||||
|
||||
// 並行アクセステスト
|
||||
test "Concurrent access safety" {
|
||||
// 複数スレッドからのアクセステスト
|
||||
}
|
||||
```
|
||||
|
||||
### Phase C: ステートフルBox修正(1週間)
|
||||
|
||||
#### C-1: コレクション系Box
|
||||
- **ArrayBox**: `Vec<Box<dyn NyashBox>>`直接保持
|
||||
- **MapBox**: `HashMap<String, Box<dyn NyashBox>>`直接保持
|
||||
- **BufferBox**: バッファ管理の簡素化
|
||||
|
||||
#### C-2: I/O系Box
|
||||
- **FileBox**: ファイルハンドル管理
|
||||
- **StreamBox**: ストリーム状態管理
|
||||
|
||||
#### C-3: P2P系Box
|
||||
- **P2PBox**: ピア管理の再設計
|
||||
- **IntentBox**: インテント処理の簡素化
|
||||
|
||||
### Phase D: 残りのBox統一(3日)
|
||||
|
||||
#### D-1: 機械的修正
|
||||
- RandomBox, DebugBox等の単純なBox
|
||||
- Arc<Mutex>除去の機械的適用
|
||||
|
||||
#### D-2: 統合テスト
|
||||
- 全Box型の動作確認
|
||||
- 相互運用性テスト
|
||||
- メモリリークチェック
|
||||
|
||||
#### D-3: パフォーマンス検証
|
||||
- ベンチマーク実行
|
||||
- ロック競合の削減確認
|
||||
- メモリ使用量の改善確認
|
||||
|
||||
## 🤖 Copilot協力タスク
|
||||
|
||||
### 自動化可能な作業
|
||||
1. **Arc<Mutex>検出スクリプト**
|
||||
```bash
|
||||
grep -r "Arc<Mutex<" src/boxes/ | wc -l
|
||||
# 現在: 50箇所以上 → 目標: 0箇所
|
||||
```
|
||||
|
||||
2. **機械的リファクタリング**
|
||||
- `Arc<Mutex<T>>` → `T`
|
||||
- `.lock().unwrap()` 除去
|
||||
- Clone実装の簡素化
|
||||
|
||||
3. **テストケース生成**
|
||||
- 各Boxの状態保持テスト
|
||||
- 並行アクセステスト
|
||||
- エッジケーステスト
|
||||
|
||||
## 📊 成功指標
|
||||
|
||||
### 定量的指標
|
||||
- [ ] Arc<Mutex>使用箇所: 0個(Box内部)
|
||||
- [ ] デッドロック発生: 0件
|
||||
- [ ] 状態保持テスト: 100%成功
|
||||
- [ ] パフォーマンス: 10%以上向上
|
||||
|
||||
### 定性的指標
|
||||
- [ ] コード可読性の向上
|
||||
- [ ] デバッグの容易さ
|
||||
- [ ] 新規開発者の理解しやすさ
|
||||
|
||||
## 🚨 リスクと対策
|
||||
|
||||
### リスク1: 既存コード互換性
|
||||
**対策**:
|
||||
- NyashBoxトレイトは変更しない
|
||||
- 段階的移行(deprecated警告)
|
||||
|
||||
### リスク2: パフォーマンス劣化
|
||||
**対策**:
|
||||
- 事前ベンチマーク取得
|
||||
- ホットパスの最適化
|
||||
|
||||
### リスク3: 実装工数超過
|
||||
**対策**:
|
||||
- 優先順位付け(SocketBox最優先)
|
||||
- Copilot活用による自動化
|
||||
|
||||
## 📅 詳細スケジュール
|
||||
|
||||
```
|
||||
Week 1:
|
||||
月: Phase A-1 パターンドキュメント
|
||||
火: Phase A-2 テンプレート作成
|
||||
水: Phase A-3 既存コードレビュー
|
||||
木: Phase B-1 SocketBox修正開始
|
||||
金: Phase B-1 SocketBox修正完了
|
||||
|
||||
Week 2:
|
||||
月: Phase B-2 HTTPServerBox修正
|
||||
火: Phase B-3 テストスイート作成
|
||||
水: Phase C-1 ArrayBox/MapBox修正
|
||||
木: Phase C-2 FileBox/StreamBox修正
|
||||
金: Phase C-3 P2PBox修正
|
||||
|
||||
Week 3:
|
||||
月: Phase D-1 残りBox修正
|
||||
火: Phase D-2 統合テスト
|
||||
水: Phase D-3 パフォーマンス検証
|
||||
木: ドキュメント最終化
|
||||
金: リリース準備
|
||||
```
|
||||
|
||||
## 🎉 期待される成果
|
||||
|
||||
1. **技術的成果**
|
||||
- デッドロック問題の根絶
|
||||
- 状態管理の信頼性向上
|
||||
- パフォーマンス改善
|
||||
|
||||
2. **開発効率向上**
|
||||
- 新Box実装の簡素化
|
||||
- デバッグ時間の短縮
|
||||
- 保守コストの削減
|
||||
|
||||
3. **Everything is Box哲学の強化**
|
||||
- より純粋なBox設計
|
||||
- 統一的な実装パターン
|
||||
- 初学者にも理解しやすい構造
|
||||
|
||||
---
|
||||
|
||||
関連ドキュメント:
|
||||
- [現在の課題](current-issues.md)
|
||||
- [SocketBox問題詳細](socket-box-problem.md)
|
||||
- [copilot_issues.txt](../../../../../予定/native-plan/copilot_issues.txt)
|
||||
@ -0,0 +1,183 @@
|
||||
# 🔌 SocketBox Arc<Mutex>二重化問題の詳細分析
|
||||
|
||||
## 🚨 問題の症状
|
||||
|
||||
### 観測された現象
|
||||
```nyash
|
||||
// テストコード
|
||||
server = new SocketBox()
|
||||
server.bind("127.0.0.1", 8080) // ✅ 成功: true
|
||||
server.isServer() // ❌ 失敗: false (期待値: true)
|
||||
```
|
||||
|
||||
### デバッグ出力
|
||||
```
|
||||
🔥 SOCKETBOX DEBUG: bind() called
|
||||
🔥 Socket ID = 17
|
||||
🔥 Arc pointer = 0x7ffd5b8a3d20
|
||||
🔥 Arc data pointer = 0x5565423a6d60
|
||||
🔥 AFTER MUTATION: is_server = true
|
||||
|
||||
🔥 SOCKETBOX DEBUG: isServer() called
|
||||
🔥 Socket ID = 17
|
||||
🔥 Arc pointer = 0x7ffd5b8a3d20
|
||||
🔥 Arc data pointer = 0x5565423a6d60 // 同じポインタ!
|
||||
🔥 IS_SERVER READ: is_server = false // しかし値は失われている
|
||||
```
|
||||
|
||||
## 🔍 根本原因の分析
|
||||
|
||||
### 1. 責務の二重化
|
||||
```rust
|
||||
// 現在のSocketBox実装
|
||||
pub struct SocketBox {
|
||||
base: BoxBase,
|
||||
listener: Arc<Mutex<Option<TcpListener>>>, // 内部ロック
|
||||
stream: Arc<Mutex<Option<TcpStream>>>, // 内部ロック
|
||||
is_server: Arc<Mutex<bool>>, // 内部ロック
|
||||
is_connected: Arc<Mutex<bool>>, // 内部ロック
|
||||
}
|
||||
|
||||
// インタープリター側
|
||||
let socket: Arc<Mutex<dyn NyashBox>> = Arc::new(Mutex::new(SocketBox::new()));
|
||||
```
|
||||
|
||||
### 2. 状態更新の問題
|
||||
```rust
|
||||
// bind()メソッド内での状態更新
|
||||
pub fn bind(&self, address: Box<dyn NyashBox>, port: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
// ...
|
||||
*self.is_server.lock().unwrap() = true; // 内部Mutexへの書き込み
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Clone実装の複雑性
|
||||
```rust
|
||||
impl Clone for SocketBox {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
base: BoxBase::new(), // 新しいID(デバッグ用)
|
||||
listener: Arc::clone(&self.listener), // Arcを共有
|
||||
stream: Arc::clone(&self.stream), // Arcを共有
|
||||
is_server: Arc::clone(&self.is_server), // Arcを共有
|
||||
is_connected: Arc::clone(&self.is_connected), // Arcを共有
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 💀 デッドロックの危険性
|
||||
|
||||
### 発生パターン
|
||||
1. インタープリターがSocketBoxをロック
|
||||
2. SocketBoxメソッドが内部フィールドをロック
|
||||
3. 別スレッドが逆順でロックを試みる
|
||||
4. デッドロック発生
|
||||
|
||||
### 実際に観測されたデッドロック
|
||||
```rust
|
||||
// PR #75修正前
|
||||
pub fn bind(&self, ...) -> Box<dyn NyashBox> {
|
||||
// ...
|
||||
let updated = SocketBox { /* ... */ };
|
||||
Box::new(updated.clone()) // ここでデッドロック
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 試みられた修正と結果
|
||||
|
||||
### PR #75: Arc<dyn NyashBox>統合
|
||||
**目的**: 状態を共有するためにArc参照を使用
|
||||
**結果**:
|
||||
- ✅ デッドロック解消
|
||||
- ❌ 状態保持問題は未解決
|
||||
|
||||
### PR #81: フィールド更新メカニズム
|
||||
**目的**: インスタンスフィールドの更新を修正
|
||||
**結果**:
|
||||
- ✅ フィールド更新は動作
|
||||
- ❌ SocketBox内部状態は依然として失われる
|
||||
|
||||
## 🎯 Gemini先生の根本解決策
|
||||
|
||||
### 設計原則の転換
|
||||
```rust
|
||||
// ❌ 現在の設計: Box自身がロック責務を持つ
|
||||
pub struct SocketBox {
|
||||
is_server: Arc<Mutex<bool>>, // Box内部でロック管理
|
||||
}
|
||||
|
||||
// ✅ 新設計: 純粋なデータコンテナ
|
||||
pub struct PlainSocketBox {
|
||||
pub listener: Option<TcpListener>,
|
||||
pub is_server: bool, // シンプルなフィールド
|
||||
}
|
||||
```
|
||||
|
||||
### 責務の明確化
|
||||
- **Box**: 純粋なデータとロジックのみ
|
||||
- **インタープリター**: すべてのロック管理を一元化
|
||||
|
||||
### 実装例
|
||||
```rust
|
||||
// 新しいbind()実装
|
||||
impl PlainSocketBox {
|
||||
pub fn bind(&mut self, addr: &str, port: u16) -> bool {
|
||||
match TcpListener::bind((addr, port)) {
|
||||
Ok(listener) => {
|
||||
self.listener = Some(listener);
|
||||
self.is_server = true; // 直接代入、ロック不要
|
||||
true
|
||||
},
|
||||
Err(_) => false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 影響分析
|
||||
|
||||
### 同じ問題を抱えるBox型
|
||||
1. **HTTPServerBox**: SocketBoxを内包、同様の問題
|
||||
2. **ArrayBox**: `Arc<Mutex<Vec<...>>>`
|
||||
3. **MapBox**: `Arc<Mutex<HashMap<...>>>`
|
||||
4. **P2PBox**: 複雑な内部状態管理
|
||||
5. その他10個のBox型
|
||||
|
||||
### リファクタリングの規模
|
||||
- 影響Box数: 15個
|
||||
- 推定作業量: 2-3週間(Phase 9.75)
|
||||
- リスク: 既存コードの互換性
|
||||
|
||||
## 🚀 移行戦略
|
||||
|
||||
### Phase A: 設計ガイドライン(3日)
|
||||
1. 新Box実装パターンの確立
|
||||
2. Arc<Mutex>禁止ルールの明文化
|
||||
3. テンプレート・サンプルコード作成
|
||||
|
||||
### Phase B: 最優先修正(1週間)
|
||||
1. SocketBox → PlainSocketBox
|
||||
2. HTTPServerBox → PlainHTTPServerBox
|
||||
3. 状態保持テストスイート作成
|
||||
|
||||
### Phase C: 全Box統一(1-2週間)
|
||||
1. 残り13個のBox型修正
|
||||
2. 統合テスト実施
|
||||
3. パフォーマンス検証
|
||||
|
||||
## 🎉 期待される効果
|
||||
|
||||
1. **デッドロック根絶**: 二重ロック構造の排除
|
||||
2. **状態整合性保証**: インタープリター一元管理
|
||||
3. **デバッグ容易性**: シンプルな実装
|
||||
4. **パフォーマンス向上**: ロック競合の削減
|
||||
5. **保守性向上**: 統一的な実装パターン
|
||||
|
||||
---
|
||||
|
||||
関連ドキュメント:
|
||||
- [現在の課題一覧](current-issues.md)
|
||||
- [Phase 9.75実装計画](phase-9-75-redesign.md)
|
||||
- [メモリ管理設計](../memory-management.md)
|
||||
Reference in New Issue
Block a user