概要
Subsecond はRustアプリケーション向けの ホットパッチ ライブラリであり、アプリを再起動せずにコード変更を反映可能。 開発時の ThinLinking によるビルド高速化も特徴。 ゲームエンジンやサーバーなどの 長時間稼働アプリ に特に有用。 Dioxusチームが開発・保守しており、 Dioxus CLI との連携が推奨される。 一部制限や注意点もあるため、詳細を確認の上で利用推奨。
Subsecond: Rust向けホットパッチライブラリの概要
- Subsecond はRustアプリケーションの実行中に コードを変更・反映 できるホットパッチ機能を提供
- ゲームエンジン ・ サーバー など、再起動コストが高い長時間稼働アプリケーション向け
- ThinLinking 技術により、開発モードでのビルド速度を大幅短縮
- Dioxusチーム が開発・保守、公式CLIツールとの親和性
- 安全性重視 の設計で、プロセスメモリを直接書き換えず外部ツールによるジャンプテーブル方式を採用
使い方
- アプリケーション・ライブラリ開発者向けに シンプルなAPI 設計
- 既存の関数呼び出しを subsecond::call でラップするだけの実装例
- 例:
for x in 0..5 { subsecond::call(|| { println!("Hello, world! {}", x); }); }
- 例:
- 実際のパッチ適用には、 Subsecondコンパイラとプロトコル を実装したサードパーティツールが必要
- 公式推奨は Dioxus CLI (
dx serve --hotpatchでホットリロード対応) - cargo binstall でCLIインストール推奨
仕組み
- ジャンプテーブル による関数コールの迂回実装
- ジャンプテーブルが最新の関数ポインタを保持し、呼び出し時に参照
- プロセスメモリの直接書き換えは非採用 で安全性確保
- 外部ツールが変更部分のみを再コンパイルし、パッチとしてジャンプテーブルを送信
- 実行中アプリが パッチを受信・適用 し、即座に新コードで動作継続
- ランタイム統合が必須、未統合時は安全なパニック発生・自動リトライ機構
ワークスペース対応
- 現状は “tip”クレート(main.rs所在クレート) のみホットパッチ対象
- 他クレートの変更は無視されるため、複数クレート構成時は注意
- 将来的に フルワークスペース対応 予定
グローバル・static・スレッドローカル変数
- グローバル・static・スレッドローカル のホットリロードを一部サポート
- 新規グローバル追加は可能だが、デストラクタは呼ばれない
- staticイニシャライザ変更は反映されない
- “tip”クレート内のスレッドローカルはパッチ適用時に初期値へリセットされる制限
- 複雑なセットアップではクラッシュやセグフォの可能性あり、将来的な改善予定
構造体のレイアウト・アラインメント
- 構造体のホットリロードは未対応
- レイアウトやアラインメント変更時、古い構造体参照でクラッシュするリスク
- フレームワーク側で re-instancing (再インスタンス化)対応推奨
- 例:Dioxusは古い状態を破棄し再構築
ポインタバージョニング
- 現状、 関数ポインタのバージョン管理なし
- 将来的にメタデータ追加予定
- DioxusやBevyはTypeIDやHotFnのptr_addressを利用し、変更検知を実装
ネスト呼び出し
- Subsecond::call はネスト可能
- パッチ適用範囲を細かく制御でき、状態消失を最小化
- 例:main関数内でforループやprintln!を個別にラップ
パッチ適用方法
- Dioxus CLI の
dx serveコマンド利用時、自動でパッチ適用 - Dioxus DevtoolsのWebSocketプロトコル経由でパッチ配信
- 独自アプリ統合時は apply_patch 関数でジャンプテーブル適用
- Dioxus Devtoolsプロトコル対応には dioxus-devtools クレートのconnectメソッド利用
- ASLR 対応のため、main関数アドレス通知が必要
ThinLinkについて
- ThinLink はSubsecond用のRust向けプログラムリンカ
- 既存リンカのラッパーで、動的リンクやジャンプテーブル生成、差分ビルドに対応
- 開発プロファイルで 500ms未満のビルド速度 を実現可能
- Dioxus CLIに自動統合、単体提供は現状未定
制限事項
- 構造体のホットリロードにはre-instancingやアンワインドが必要
- static変数は追跡されるがデストラクタは呼ばれない
- スレッドローカルの初期化・リセット問題
プラットフォーム対応
- 主要プラットフォーム 全対応
- Android(arm64-v8a, armeabi-v7a)
- iOS(arm64, シミュレータのみ、実機は未対応)
- Linux(x86_64, aarch64)
- macOS(x86_64, aarch64)
- Windows(x86_64, arm64)
- WebAssembly(wasm32)
- 新規プラットフォーム追加希望は Subsecondリポジトリ でIssue提出推奨
Subsecondバッジの追加
- フレームワーク作者向けにREADME用 Subsecondバッジ 提供
- 例:
[](https://crates.io/crates/subsecond)
- 例:
ライセンス
- MITライセンス 採用
- 詳細はLICENSEファイル参照
サポート・支援
- Dioxusチーム による開発
- GitHubスポンサーやDioxus Deploy(準備中)による支援歓迎
主な型・関数
- HotFn :ホットリロード可能な関数型
- HotFnPanic :call時に発生するパニック型(リトライ処理用)
- HotFnPtr :ホットパッチ対象関数へのポインタ
- JumpTable :ジャンプテーブル型
- PatchError :パッチ適用時のエラー型
- HotFunction :ホットパッチ可能型を実現するトレイト
- apply_patch :ジャンプテーブルを用いたパッチ適用関数
- call :ホットリロード対応関数呼び出し。上位コード変更時はパニック発生・アンワインド
- register_handler :ハンドラ登録用関数