fix: Correct HttpRequestBox method_id mapping in nyash.toml
Fixed the method ID order in HttpRequestBox configuration to match plugin implementation: - path: method_id 1 (was incorrectly 2) - readBody: method_id 2 (was incorrectly 3) - respond: method_id 3 (was incorrectly 1) This resolves the 45-day debugging issue where req.respond(resp) was calling the wrong plugin method, causing HTTP responses to have empty bodies. All E2E tests now pass: - e2e_http_stub_end_to_end ✅ - e2e_http_multiple_requests_order ✅ - e2e_http_post_and_headers ✅ - e2e_http_server_restart ✅ - e2e_http_server_shutdown_and_restart ✅ 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
72
docs/development/box_identity_and_copy_semantics.md
Normal file
72
docs/development/box_identity_and_copy_semantics.md
Normal file
@ -0,0 +1,72 @@
|
||||
Box Identity and Copy Semantics (Nyash)
|
||||
|
||||
Context
|
||||
- In Nyash, everything is a Box. Some boxes carry identity (external handles, stateful resources), while others are pure values.
|
||||
- Picking clone_box vs share_box is critical: getting it wrong can silently fork state or break handle identity (e.g., plugin/socket/file handles).
|
||||
|
||||
Key Terms
|
||||
- Identity Box: Represents an external or stateful handle where the instance_id (or similar) must remain stable across uses. Examples: PluginBoxV2 (all plugin boxes), Socket boxes, FileBox, DB handles.
|
||||
- Value Box: Pure data containers where cloning yields an equivalent value. Examples: StringBox, IntegerBox, JSONBox, ArrayBox/MapBox (when used as data).
|
||||
|
||||
Rules of Thumb
|
||||
- When preserving identity matters (handle/connection/descriptor): use share_box.
|
||||
- When passing or returning pure values: use clone_box (or deep copy APIs) so callers can freely mutate their copy.
|
||||
- Do not call clone_box on identity boxes during common control flows like method dispatch, result unwrapping, or variable assignment unless you’re explicitly birthing a new instance.
|
||||
|
||||
Where mistakes commonly happen
|
||||
1) Result unwrap (ResultBox.get_value)
|
||||
- Wrong: always clone_box() — duplicates plugin handles and changes instance_id.
|
||||
- Right: if value is PluginBoxV2 (or any identity box), return share_box(); else clone_box().
|
||||
|
||||
2) Method dispatch (receiver preparation)
|
||||
- Wrong: always clone the receiver box before method call.
|
||||
- Right: if the VM stores BoxRef(Arc<dyn NyashBox>), use Arc::share_box() for the receiver; only clone for value boxes.
|
||||
|
||||
3) Environment/variable storage
|
||||
- Wrong: eagerly clone_box() on set/assign.
|
||||
- Right: keep as BoxRef (Arc) where semantics require identity; only copy for value semantics.
|
||||
|
||||
4) Returning plugin results
|
||||
- Ensure loader returns PluginBoxV2 with the exact instance_id provided by the plugin, wrapped as BoxRef. Avoid any implicit clone.
|
||||
|
||||
Concrete patterns
|
||||
- In ResultBox.get_value():
|
||||
- if val.is::<PluginBoxV2>() -> return val.share_box()
|
||||
- else -> val.clone_box()
|
||||
|
||||
- In VMValue conversions:
|
||||
- VMValue::from_nyash_box: store as BoxRef(Arc<dyn NyashBox>) for identity-bearing boxes (default safe choice).
|
||||
- VMValue::to_nyash_box: for BoxRef -> share_box().
|
||||
|
||||
- In plugin method dispatch (PluginBoxV2):
|
||||
- Identify receiver as PluginBoxV2 and pass its instance_id to FFI directly (avoid cloning receiver).
|
||||
|
||||
Anti-patterns to avoid
|
||||
- Using clone_box blindly in:
|
||||
- Result unwrap paths
|
||||
- Method receiver preparation
|
||||
- Field access and variable bindings for identity boxes
|
||||
|
||||
Design guidance
|
||||
- Consider tagging boxes with an identity flag:
|
||||
- Add BoxCore::is_identity() -> bool (default false; override to true for PluginBoxV2, Socket/File/DB boxes).
|
||||
- Provide a helper: clone_or_share_by_semantics(box: &dyn NyashBox) that calls share for identity and clone for values.
|
||||
- Add debug assertions/logs in dev builds when a PluginBoxV2’s instance_id unexpectedly changes across a single logical flow (indicative of unintended clone).
|
||||
|
||||
Testing checklist
|
||||
- Log instance_id for plugin boxes at:
|
||||
- client.get/post result (resp_id)
|
||||
- ResultBox.get_value return (should match)
|
||||
- Method dispatch receiver (should match)
|
||||
- readBody()/write logs (should match)
|
||||
- For e2e tests, assert that write/mirror/read use the same response id.
|
||||
|
||||
Migrations for existing code
|
||||
- Update ResultBox.get_value to share PluginBoxV2.
|
||||
- Audit call sites that do clone_box() before method dispatch or storage; prefer BoxRef + share for identity boxes.
|
||||
- Ensure plugin loader returns PluginBoxV2 as BoxRef, not cloned.
|
||||
|
||||
Future improvements
|
||||
- Static lint: forbid clone_box on types that implement BoxCore::is_identity() == true in critical paths (unwrap, dispatch, assign).
|
||||
- Provide a macro/helper to explicitly mark intent: share!(x), clone_value!(x) to make code review easier.
|
||||
|
||||
@ -23,20 +23,25 @@
|
||||
- デリゲーションテスト: ❓ 未実装の可能性
|
||||
- VMテスト: ❌ 失敗(VMはまだプラグインBox未対応)
|
||||
|
||||
### 🎯 次のタスク (Phase 9.78b)
|
||||
### 🎯 次のタスク(MIR→VM チェック / 命令最適化)
|
||||
|
||||
#### Step 3: BoxFactory dyn化(優先度: 高)
|
||||
- 現在: `HashMap<String, Box<dyn Fn() -> Arc<dyn NyashBox>>>`
|
||||
- 目標: `HashMap<String, Arc<dyn BoxFactory>>`
|
||||
- 利点: プラグインBoxもVMで統一処理可能
|
||||
1) MIR→VM 変換の健全性チェック(短期)
|
||||
- 現行 MIR 命令 → VM 命令のマッピング表を作成
|
||||
- E2E/サンプルを VM バックエンドで実行し、MIR→VM 変換ログを収集
|
||||
- 例外系・Result正規化(returns_result)の経路を VM で確認
|
||||
|
||||
#### Step 4: グローバル排除
|
||||
- `get_global_registry()` → `runtime.registry`
|
||||
- `get_global_loader_v2()` → `runtime.plugin_loader`
|
||||
2) 命令使用実績の計測(短期)
|
||||
- 実際に使用されている VM 命令を計測(実行ログ/カウンタ)
|
||||
- 現行宣言33命令 → 実使用コア命令の抽出
|
||||
|
||||
#### Step 5: SharedState分解
|
||||
- 巨大なSharedState構造体を分割
|
||||
- Box管理、メソッド管理、スコープ管理を分離
|
||||
3) 命令セットのダイエット検討(中期)
|
||||
- 目標: 26命令(docsの合意値)
|
||||
- 代替可能/統合可能な命令の提案と互換性影響の洗い出し
|
||||
- 実験フラグで26命令版のVMを試作(段階移行)
|
||||
|
||||
4) ドキュメント更新(短期)
|
||||
- 現状の命令一覧と目標26命令の整合(reference/architecture/)
|
||||
- 計測結果(使用頻度)と統合方針を追記
|
||||
|
||||
### 📝 メモ
|
||||
- ChatGPT5がプラグインBoxメソッド呼び出しに引数/戻り値サポートを追加
|
||||
@ -44,10 +49,10 @@
|
||||
- Rustの借用チェッカーとの格闘の跡が見られる(複数回の修正)
|
||||
|
||||
### 🔧 推奨アクション
|
||||
1. セッション再起動してBashコマンドを復活
|
||||
2. ビルド実行: `cargo build --release -j32`
|
||||
3. E2Eテスト実行: `cargo test e2e_plugin_filebox --features plugins -- --show-output`
|
||||
4. VMプラグイン統合の実装開始(Phase 9.78b Step 3)
|
||||
1. VMバックエンドでの実行ログ化(命令発行ログ/カウンタ)
|
||||
2. マッピング表作成(MIR→VM)と欠落/冗長命令の洗い出し
|
||||
3. 26命令案のPoCブランチ作成→E2Eで回帰確認
|
||||
4. docs更新(命令一覧、設計意図、移行戦略)
|
||||
|
||||
---
|
||||
最終更新: 2025年8月20日 22:45
|
||||
最終更新: 2025年8月22日 03:30(MIR→VM/命令最適化タスク追加)
|
||||
|
||||
Reference in New Issue
Block a user