Skip to content

chore: fix remaining issues with rivetkit-core#4701

Draft
NathanFlurry wants to merge 3 commits into04-12-feat_import_export_actorsfrom
04-22-chore_fix_remaining_issues_with_rivetkit-core
Draft

chore: fix remaining issues with rivetkit-core#4701
NathanFlurry wants to merge 3 commits into04-12-feat_import_export_actorsfrom
04-22-chore_fix_remaining_issues_with_rivetkit-core

Conversation

@NathanFlurry
Copy link
Copy Markdown
Member

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@railway-app
Copy link
Copy Markdown

railway-app Bot commented Apr 23, 2026

🚅 Deployed to the rivet-pr-4701 environment in rivet-frontend

Service Status Web Updated (UTC)
frontend-inspector ❌ Build Failed (View Logs) Web Apr 23, 2026 at 11:26 am
frontend-cloud ❌ Build Failed (View Logs) Web Apr 23, 2026 at 11:26 am
kitchen-sink ❌ Build Failed (View Logs) Web Apr 23, 2026 at 11:26 am
website 😴 Sleeping (View Logs) Web Apr 23, 2026 at 4:05 am
ladle ❌ Build Failed (View Logs) Web Apr 23, 2026 at 3:54 am
mcp-hub ✅ Success (View Logs) Web Apr 23, 2026 at 3:53 am

Copy link
Copy Markdown
Member Author

NathanFlurry commented Apr 23, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@claude
Copy link
Copy Markdown

claude Bot commented Apr 23, 2026

PR #4701 Review: chore: fix remaining issues with rivetkit-core

Status: DRAFT — 318 files changed, +30,457 / -18,543

Summary

This is a large, multi-layered refactor of rivetkit-core:

  1. Registry split — monolithic src/registry.rs (4,053 lines) decomposed into src/registry/ submodules: http.rs, inspector.rs, inspector_ws.rs, websocket.rs, actor_connect.rs, dispatch.rs, envoy_callbacks.rs.
  2. ActorTask backpressure — all sends now use try_send_lifecycle_command / try_send_dispatch_command via try_reserve, not blocking send, with structured actor.overloaded errors.
  3. Anti-polling — replaces the 10 ms polling loop in handle_fetch with an event-driven AsyncCounter / Notify-based wait_for_http_requests_idle().
  4. Engine process managerengine_process.rs added to spawn and health-check a local engine binary.
  5. Error consolidation — new error.rs with #[derive(RivetError)] enums for lifecycle, runtime, protocol, SQLite, and engine-process errors.
  6. Preload extractionpreload.rs handles PreloadedPersistedActor and PreloadedKv.
  7. ActorVars removalvars.rs deleted; vars were never wired to core persistence.
  8. Test expansiontask.rs grows to 28 tests; kv.rs, state.rs, context.rs tests added.

Code Quality

Positives:

  • Registry decomposition is a clear win. New registry/ layout is clean and well-scoped.
  • try_reserve-before-construct pattern in try_send_lifecycle_command / try_send_dispatch_command correctly avoids orphaned reply oneshot senders on full channels.
  • AsyncCounter correctly arms Notify::notified() before the value check, avoiding TOCTOU.
  • RegionGuard / CountGuard RAII wrappers decrement on drop including during panic unwind (verified by test).
  • Reply<T> sends DroppedReply from Drop — no oneshot is silently abandoned.
  • EngineProcessManager::wait_for_engine_health uses exponential backoff and correctly uses rivet_pools::reqwest::client().
  • New RivetError-derived enums follow the project pattern exactly.

Issues:

1. RegistryDispatcher.factories: HashMap (minor convention)

factories is a plain std::collections::HashMap read from multiple async contexts. CLAUDE.md says to use scc::HashMap for concurrent maps. Functionally safe since it is read-only post-construction, but inconsistent with the rest of the dispatcher.

Location: rivetkit-rust/packages/rivetkit-core/src/registry/mod.rs:118

2. Test polling loops (convention)

Test helpers in tests/modules/task.rs and tests/modules/context.rs use:

for _ in 0..50 {
    if counter.load(Ordering::SeqCst) >= expected { return; }
    sleep(Duration::from_millis(10)).await;
}

CLAUDE.md explicitly prohibits loop { check; sleep } polling. The new AsyncCounter API (with wait_zero) should be used instead.


Potential Bugs

3. Untracked detached spawn in on_actor_stop_with_completion (medium)

on_actor_stop_with_completion calls tokio::spawn(async move { dispatcher.stop_actor(...).await }) and returns immediately. The task is not tracked in a JoinSet, so in-flight stops are silently abandoned on runtime shutdown.

Location: rivetkit-rust/packages/rivetkit-core/src/registry/envoy_callbacks.rs:59-72

4. Inspector auth bypass via handle_inspector_http_in_runtime (security/informational)

When handle_inspector_http_in_runtime is true, handle_inspector_fetch returns Ok(None) early, skipping the core-layer auth check. CLAUDE.md says inspector auth should live in rivetkit-core. This is a latent risk if any TS-side path omits auth.

Location: rivetkit-rust/packages/rivetkit-core/src/registry/inspector.rs:27-30

5. Stopping actor returned without caller awareness (low)

active_actor() returns the instance even when Stopping, only logging a warning. Callers dispatching work to a stopping actor receive actor.overloaded from channel rejection rather than a more precise error.

Location: rivetkit-rust/packages/rivetkit-core/src/registry/mod.rs:683-695


Performance

  • Positive: HTTP sleep rearm is now event-driven via wait_for_http_requests_idle() — no more 10 ms wasted wakeups.
  • AsyncCounter observer notification iterates vecs under a std::sync::Mutex on every counter operation. Fine for current usage but worth noting if observer counts grow.

Test Coverage

Good additions: preloaded_kv_* tests, on_state_change_* tests (including reentrant mutation detection), 28 task lifecycle tests, async_counter.rs unit tests, RegionGuard panic-unwind test.

Coverage gaps:

  • EngineProcessManager has no unit tests (health-check backoff, SIGTERM/SIGKILL paths are untested).
  • on_actor_stop_with_completion race with starting_instances is untested.
  • wait_for_pending_writes has no dedicated test despite being a complex multi-loop shutdown coordination function.

CLAUDE.md Compliance

Convention Status
rivet.dev, no rivet.gg Pass
Tracing macros, structured fields Pass
#[derive(RivetError)] pattern Pass
No Mutex<HashMap> / RwLock<HashMap> Mostly pass (see item 1; connections: RwLock<BTreeMap> is pre-existing/ordered)
scc::HashMap for concurrent maps Mostly pass (actor_instances, starting_instances, pending_stops correct)
No vi.mock / jest.mock Pass

Summary

This is a well-structured, high-quality refactor. Key items before merge:

  1. Medium: Track the spawned task in on_actor_stop_with_completion (use a JoinSet) so in-flight stops drain on graceful shutdown.
  2. Convention: Replace sleep(10ms) polling loops in test helpers with AsyncCounter / Notify event-driven waits.
  3. Convention: factories: HashMap in RegistryDispatcher should be scc::HashMap.
  4. Informational: handle_inspector_http_in_runtime auth bypass — ensure TS-side inspector routes always apply auth when this flag is set.
  5. Informational: Add unit tests for EngineProcessManager and wait_for_pending_writes before merge.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Preview packages published to npm

Install with:

npm install rivetkit@pr-4701

All packages published as 0.0.0-pr.4701.d2c139c with tag pr-4701.

Engine binary is shipped via @rivetkit/engine-cli on linux-x64-musl, linux-arm64-musl, darwin-x64, and darwin-arm64. Windows users should use the release installer or set RIVET_ENGINE_BINARY.

Docker images:

docker pull rivetdev/engine:slim-d2c139c
docker pull rivetdev/engine:full-d2c139c
Individual packages
npm install rivetkit@pr-4701
npm install @rivetkit/react@pr-4701
npm install @rivetkit/rivetkit-napi@pr-4701
npm install @rivetkit/workflow-engine@pr-4701

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant