(Issue)- unbounded memory growth during actors cycling.
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
- #5634 @AlSh007 による — マージされずにクローズ
評価
調査の方向性
rivetkit-typescript/packages/rivetkit-napi/src/actor_context.rs から始め、ActorContextShared::reset_runtime_state() とその Drop 実装を併せて読みます。有効な Node.js Env が利用可能な場合に napi::Ref がどのように解放されるか、また actor の wake サイクルがこれらのパスにどのように到達するかを追跡します。繰り返しの sleep/wake サイクルによって、panic や無制限の増加なしに JS 参照が解放されれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary:-
ActorContextShared::reset_runtime_state() in rivetkit-napi uses std::mem::forget to avoid a panic when dropping a napi::Ref on a Tokio worker thread (where no Node.js Env is available). This leaks one JS object reference slot per actor wake cycle. Over time in long-running processes with many actors cycling through sleep/wake, this is unbounded memory growth.
Problem:-
When an actor wakes from sleep, reset_runtime_state() is called to clear the previous JS state object. The napi::Ref type requires calling .unref(env) with a valid Node.js Env handle to properly release the reference. But reset_runtime_state() runs on a Tokio worker thread where no Env exists.
The current code uses std::mem::forget(old) to suppress the destructor. This avoids a debug_assert panic in napi-rs, but permanently leaks the underlying V8 reference slot.
The same pattern appears in the Drop impl for ActorContextShared.
File: rivetkit-typescript/packages/rivetkit-napi/src/actor_context.rs
if let Some(old) = self.runtime_state.lock().take() {
std::mem::forget(old);
}
Impact:-
- Rivet Actors are designed to sleep and wake frequently. An actor that wakes 100 times leaks 100 JS reference slots.
- The leak is per-actor, per-wake. A deployment with thousands of actors cycling through sleep/wake accumulates leaked references without bound.
- The only relief is process restart.
- 主要言語
- Rust
- スター
- 6.5k
- フォーク
- 291
- 平均マージ
- 16時間 58分
- マージ済み PR(30日)
- 33
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドなし
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
rivet-dev/rivet のほかの issue
-
rivetkit client: ActorConn debug log prints action arguments対応中かも @Jbansal2 が 1 日前に担当しました。 オープン
難易度 1/5 1時間未満 初心者へのやさしさ 80/100
rivet-dev/rivet#5955 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
rivetkit 3.0: HTTP 400 overloaded on node pool upsert is treated as fatal and exits the processオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
rivet-dev/rivet#5933 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
effect: action on a missing actor instance fails as internal_error instead of actor.aborted対応中かも @kunalgoesbyken が 10 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
rivet-dev/rivet#5891 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Rust client drops connection-level errors when actionId is null (JSON/CBOR)対応中かも @DibbayajyotiRoy が 33 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
rivet-dev/rivet#5819 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Queue docs say completable messages are removed on receive, but they stay stored until complete()対応中かも @Saisharathchandranandnetha が 44 日前に担当しました。 オープン
難易度 1/5 1〜3時間 初心者へのやさしさ 91/100
rivet-dev/rivet#5762 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
rivet-dev/rivet の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 77/100
near/near-sdk-rs#1676 ·
メンテナーはふだん 2 日以内に返信
-
auto:producer auto:security
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
fritzprix/libr-agent#2595 ·
メンテナーはふだん 1 日以内に返信
-
area:fs type:fix
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
Tripstack-Corp/spyc#1002 ·
メンテナーはふだん 1 日以内に返信
-
github_actions security
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
dekobon/big-code-analysis#1815 ·
メンテナーはふだん 1 日以内に返信
-
[Detail Bug] Request logs can be forged via control characters in fetch object keys (log injection)オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
s2-streamstore/cachey#211 ·
メンテナーはふだん 1 日以内に返信