feat: Add parallel HTTP server E2E tests and enhance plugin system

- Add e2e_plugin_net_additional.rs with parallel server tests
- Fix test to properly handle request objects (no double accept)
- Add comprehensive net-plugin documentation
- Implement debug tracing for method calls
- Enhance plugin lifecycle documentation
- Improve error handling in plugin loader
- Add leak tracking infrastructure (for future use)
- Update language spec with latest plugin features

This enhances test coverage for concurrent HTTP servers and improves
the overall plugin system documentation and debugging capabilities.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-08-22 05:01:11 +09:00
parent 98e9893bf5
commit f2761004d3
20 changed files with 1288 additions and 105 deletions

View File

@ -21,6 +21,25 @@
- プラグインの動作確認とデバッグに使用
- `tools/plugin-tester`ツールの使用方法
- **[plugin_lifecycle.md](./plugin_lifecycle.md)** - ライフサイクル/RAII/シングルトン/ログ
- 共有ハンドル、scope終了時の扱い、`shutdown_plugins_v2()` の動作
- NetPluginHTTP/TCPの並列E2E時の注意点
- **[net-plugin.md](./net-plugin.md)** - NetプラグインHTTP/TCP PoC
- GET/POST、ヘッダ、Content-Length、環境変数によるログ
### ⚙️ 戻り値のResult化B案サポート
- `nyash.toml` のメソッド定義に `returns_result = true` を付けると、
- 成功: `Ok(value)``ResultBox` に包んで返す
- 失敗BID負エラー: `Err(ErrorBox(message))` を返す(例外にはしない)
```toml
[libraries."libnyash_example.so".ExampleBox.methods]
dangerousOp = { method_id = 10, returns_result = true }
```
未指定の場合は従来通り(成功=生値、失敗=例外として伝播)。
- **[filebox-bid-mapping.md](./filebox-bid-mapping.md)** - 参考資料
- FileBox APIとプラグイン実装の対応表
- API設計の参考として有用
@ -84,4 +103,4 @@ cargo build --release
---
**Status**: Phase 2 Documentation Reorganization - Completed
**Last Updated**: 2025-08-20
**Last Updated**: 2025-08-20

View File

@ -0,0 +1,72 @@
# Net Plugin (HTTP over TCP PoC)
最終更新: 2025-08-22
## 概要
- `nyash-net-plugin` は Socket/HTTP をプラグインとして提供します。
- HTTP は最小限の HTTP/1.1 実装GET/POST、ヘッダ、Content-Lengthを実ソケットで処理します。
## 提供Box
- `SocketServerBox`, `SocketClientBox`, `SocketConnBox`
- `HttpServerBox`, `HttpRequestBox`, `HttpResponseBox`, `HttpClientBox`
`nyash.toml` 定義例(抜粋)はリポジトリ直下の `nyash.toml` を参照。
## 動作仕様HTTP
- Server
- `start(port)`: TCP待受を開始
- `accept()`: 接続受理リクエスト簡易パースpath/body`HttpRequestBox` を返す
- `HttpRequestBox.respond(resp)`: `resp` の status/header/body を HTTP/1.1 として送出(`Connection: close`
- Client
- `get(url)`, `post(url, body)`: host:port に接続し、HTTP/1.1 リクエストを送出
- `HttpResponseBox` は遅延受信。`readBody()/getStatus()/getHeader()` 呼び出し時に受信・パース
制限:
- Chunked/Keep-Alive/HTTP/2は非対応PoC。Content-Length のみ対応。
## エラーモデルPoC
- BID-FFI の負値(例: `-5` PluginErrorは Nyash 側で例外(`RuntimeFailure`)として扱われます。
- タイムアウト系Socket の `acceptTimeout/recvTimeout`)はエラーではなく、以下の値を返します:
- `acceptTimeout(ms)`: タイムアウト時は `void`
- `recvTimeout(ms)`: タイムアウト時は 空 `bytes`長さ0の文字列
将来の整合:
- `ResultBox` での返却に対応する設計(`Ok(value)`/`Err(ErrorBox)`)を検討中。
- `nyash.toml` のメソッド宣言に戻り値型Resultを記載し、ランタイムで自動ラップする案。
## 並列E2E運用の注意
- 各テストで異なるポートを使用(例: 8080/8081/8090/8091...
- サーバの `stop()` と再起動時はポート開放の遅延に注意(短い待機を挟むと安定)
- ログを有効化して競合や順序の問題を診断可能
## ログ出力
環境変数で簡易ログを有効化できます。
```bash
export NYASH_NET_LOG=1
export NYASH_NET_LOG_FILE=net_plugin.log
```
stderr とファイルの両方に出力されます。
## 例
```nyash
local srv, cli, r, req, resp
srv = new HttpServerBox()
srv.start(8080)
cli = new HttpClientBox()
r = cli.get("http://localhost:8080/hello")
req = srv.accept()
resp = new HttpResponseBox()
resp.setStatus(200)
resp.setHeader("X-Test", "V")
resp.write("OK")
req.respond(resp)
// client side
print(r.getStatus())
print(r.getHeader("X-Test"))
print(r.readBody())
```

View File

@ -0,0 +1,53 @@
# Plugin Lifecycle and Box RAII
最終更新: 2025-08-22
## 概要
NyashのBoxには「ユーザー定義Box」「ビルトインBox」「プラグインBox」があります。いずれもRAII取得した資源は所有者の寿命で解放に従いますが、プラグインBoxは共有やシングルトン運用があるため、追加ルールがあります。
## 共通ライフサイクル(ユーザー/ビルトイン/プラグイン)
- インスタンスの寿命が尽きると、強参照フィールドpublic/privateに対し順に `fini()` が呼ばれ解放weak はスキップ)
- `local` 変数のスコープを抜けると、そのスコープで生成されたインスタンスは解放対象
- 明示的に `fini()` が呼ばれた場合も同様に後処理を実施
補足:
- これらは Nyash のスコープトラッカにより実施されます
- 解放順は生成の逆順LIFOで、カスケード `fini` を保証します
## プラグインBoxの特則シングルトン
- シングルトン(`nyash.toml`
- プラグインのBox型は `singleton = true` を宣言可能
- ローダが起動時に `birth()` し、以後は同一ハンドルを共有して返却
- シャットダウン時(`shutdown_plugins_v2()` など)に一括 `fini()` されます
補足:
- Nyashは参照カウントを採用しません。解放は「スコープ終了」または「明示的`fini`」のみで決まります(自己責任モデル)。
- プラグインBoxも同じルールです。スコープ終了時に`fini`され、以後の利用はエラーUse after fini
- 長寿命が必要なケースは「シングルトン」で運用してください個別のBoxに特例は設けない
### 例: `nyash.toml` 抜粋
```toml
[libraries."libnyash_counter_plugin.so".CounterBox]
type_id = 7
singleton = true
```
## Net PluginHTTP/TCP運用メモ
- ログ
- `NYASH_NET_LOG=1` で有効化、`NYASH_NET_LOG_FILE=net_plugin.log` 出力先
- 並列実行とポート
- E2Eや並列CIではポート競合を避けるため、テスト毎にポートを明示例: 8080, 8081, ...
- サーバ終了タイミング(`stop()`/スコープ終了)とクライアント接続の順序に注意
## ベストプラクティス
- ユーザー/ビルトインBox
- フィールドの weak 指定(循環参照の解消)を活用
- 必要に応じて明示 `fini()` を呼び、高価な資源(ファイル/ソケット等)を早期解放
- プラグインBox
- シングルトン化が望ましい長寿命資源(サーバ、デバイス)に `singleton = true`
- 複数スコープで共有される可能性がある値は、スコープ終了時に自動 `fini` されないことを前提に設計
- 終了前に `shutdown_plugins_v2()` を呼ぶと単一箇所で確実に `fini` を実行可能
## 実装参照
- スコープ追跡: `src/scope_tracker.rs`(スコープ終了時の `fini` 呼出し、プラグインBox自動 `fini` 回避)
- プラグインローダ: `src/runtime/plugin_loader_v2.rs`(シングルトン生成・保持・シャットダウン、`PluginHandleInner::drop``fini`