Files
hakorune/docs/reference/plugin-system/plugin_lifecycle.md
tomoaki ab76e39036 feat(parser): Phase 285A1.4 & A1.5 - Weak field sugar + Parser hang fix
A1.4: Add sugar syntax `public weak parent` ≡ `public { weak parent }`
A1.5: Fix parser hang on unsupported `param: Type` syntax

Key changes:
- A1.4: Extend visibility parser to handle weak modifier (fields.rs)
- A1.5: Shared helper `parse_param_name_list()` with progress-zero detection
- A1.5: Fix 6 vulnerable parameter parsing loops (methods, constructors, functions)
- Tests: Sugar syntax (OK/NG), parser hang (timeout-based)
- Docs: lifecycle.md, EBNF.md, phase-285a1-boxification.md

Additional changes:
- weak() builtin implementation (handlers/weak.rs)
- Leak tracking improvements (leak_tracker.rs)
- Documentation updates (lifecycle, types, memory-finalization, etc.)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 07:44:50 +09:00

3.6 KiB
Raw Blame History

Plugin Lifecycle and Box RAII

最終更新: 2025-08-22

概要

NyashのBoxには「ユーザー定義Box」「ビルトインBox」「プラグインBox」があります。いずれもRAII取得した資源は所有者の寿命で解放に従いますが、プラグインBoxは共有やシングルトン運用があるため、追加ルールがあります。

共通ライフサイクル(ユーザー/ビルトイン/プラグイン)

  • fini() は論理的な終了use-after-fini禁止であり、外部資源fd/socket/native handle など)を決定的に解放するための SSOT です。
  • local のスコープを抜けると、その binding は drop されます(= その binding が保持していた strong 参照が 1 つ減る)。
    • その時点で「最後の strong 参照」になれば物理的な解放が起きますが、タイミングは実装依存です。
  • 共有・循環参照がありうるため、スコープ終了“だけ”に fini() を期待しないでください。必要な資源は fini() / cleanup / shutdown_plugins_v2() で明示的に閉じます。

補足:

  • 言語レベルの SSOT は docs/reference/language/lifecycle.md を参照してください(スコープ/所有/weak/fini/GC
  • fini() の中で「strong-owned フィールドを順に fini()」するカスケード設計は有用ですが、最終的な順序や禁止事項は SSOT に従います。

プラグインBoxの特則シングルトン

  • シングルトン(nyash.toml
    • プラグインのBox型は singleton = true を宣言可能
    • ローダが起動時に birth() し、以後は同一ハンドルを共有して返却
    • シャットダウン時(shutdown_plugins_v2() など)に一括 fini() されます

補足:

  • Nyashの実装は Box 値を参照(共有)として扱います。物理的な生存は strong 参照の有無に依存しうる一方、fini() は論理的な終了use-after-fini禁止です。
  • プラグインBoxも同じルールです。fini 後の利用はエラーUse after fini
  • 長寿命が必要なケースは「シングルトン」で運用してください個別のBoxに特例は設けない

例: nyash.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::dropfini