(Issue)- unbounded memory growth during actors cycling.

Aperta
#5,607 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@AlSh007 ci sta già lavorando.

Dal 2/9/2026.

  • #5634 di @AlSh007 — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
55/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
node.js, rust
Ambito
backend

Direzione di ricerca

Inizia da rivetkit-typescript/packages/rivetkit-napi/src/actor_context.rs, leggendo ActorContextShared::reset_runtime_state() insieme alla sua implementazione di Drop. Traccia come viene rilasciato napi::Ref quando è disponibile un Node.js Env valido e come i cicli di risveglio dell’actor raggiungono questi percorsi. Il lavoro è completato quando cicli ripetuti di sospensione/risveglio rilasciano i riferimenti JS senza panic né crescita illimitata.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.
Lingua principale
Rust
Stelle
6.5k
Fork
291
Merge medio
18h 45m
PR unite (30g)
38

Preparare l'ambiente

  • Nessun Dockerfile né file Docker Compose
  • Ha un modello di pull request
  • Nessuna guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di rivet-dev/rivet

Tutte le issue di rivet-dev/rivet

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.