(Issue)- unbounded memory growth during actors cycling.
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 55/100
Línea de trabajo
Comienza en rivetkit-typescript/packages/rivetkit-napi/src/actor_context.rs, leyendo ActorContextShared::reset_runtime_state() junto con su implementación de Drop. Traza cómo se libera napi::Ref cuando hay un Node.js Env válido disponible y cómo los ciclos de activación del actor llegan a estos caminos. La tarea está terminada cuando los ciclos repetidos de suspensión/activación liberan las referencias de JS sin panic ni crecimiento ilimitado.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Rust
- Estrellas
- 6.5k
- Forks
- 291
- Merge medio
- 18 h 45 min
- PR fusionados (30 d)
- 38
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Sin guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de rivet-dev/rivet
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 80/100
rivet-dev/rivet#5955 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
rivetkit 3.0: HTTP 400 overloaded on node pool upsert is treated as fatal and exits the processAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
rivet-dev/rivet#5933 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
effect: action on a missing actor instance fails as internal_error instead of actor.abortedPosiblemente ocupada @kunalgoesbyken la tomó hace 8 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
rivet-dev/rivet#5891 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Rust client drops connection-level errors when actionId is null (JSON/CBOR)Posiblemente ocupada @DibbayajyotiRoy la tomó hace 30 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
rivet-dev/rivet#5819 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Queue docs say completable messages are removed on receive, but they stay stored until complete()Posiblemente ocupada @Saisharathchandranandnetha la tomó hace 41 días. Abierto
Dificultad 1/5 1-3 horas Aptitud para principiantes 91/100
rivet-dev/rivet#5762 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de rivet-dev/rivet
Issues similares
-
Dificultad 1/5 1-3 horas Aptitud para principiantes 70/100
OpenZeppelin/openzeppelin-relayer#967 ·
Los mantenedores suelen responder en 1 día
-
DecisionOutcome::label() / n_dosed(): engine-side mapping so downstream needs no wildcard armAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
src/runs.rs:1987: a missing --source-run-id now answers 400 "Source run ... does not exist", not 404Abiertonightly-audit
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
antithesishq/snouty#602 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
libnativeapi/nativeapi#21 ·