Files
hakorune/docs/説明書/reference/box-design/implementation-notes/socket-box-problem.md
Moe Charm e0f0a658e6 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>
2025-08-15 07:47:09 +09:00

183 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🔌 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)