Skip to content

Commit d7cd40d

Browse files
committed
chore: fix remaining issues with rivetkit-core
1 parent d6d5a69 commit d7cd40d

315 files changed

Lines changed: 30432 additions & 18433 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# rivetkit-core counter-poll audit
2+
3+
Date: 2026-04-22
4+
Story: US-027
5+
6+
## Scope
7+
8+
Searched `rivetkit-rust/packages/rivetkit-core/src/` for:
9+
10+
- `loop { ... sleep(Duration::from_millis(_)).await; ... }`
11+
- `loop { ... tokio::time::sleep(...).await; ... }`
12+
- `while ... { ... sleep(Duration::from_millis(_)).await; ... }`
13+
- `AtomicUsize`, `AtomicU32`, `AtomicU64`, and `AtomicBool` fields with async waiters
14+
15+
## Converted polling sites
16+
17+
- `registry.rs::Registry::handle_fetch`
18+
- Classification before: polling.
19+
- Problem: after an HTTP request, the rearm task checked `can_sleep() == ActiveHttpRequests` and slept in 10 ms slices until the envoy HTTP request counter reached zero.
20+
- Fix: added `SleepController::wait_for_http_requests_idle(...)` and `ActorContext::wait_for_http_requests_idle()`, both backed by the existing `AsyncCounter` zero-notify registration on `work.idle_notify`.
21+
- Coverage: added `http_request_idle_wait_uses_zero_notify` to prove the waiter wakes on decrement-to-zero without advancing a polling interval.
22+
23+
## Event-driven sites
24+
25+
- `actor/state.rs::wait_for_save_request`
26+
- Classification: event-driven.
27+
- Uses `save_completion: Notify`; waiters arm `notified()` before re-checking `save_completed_revision`.
28+
29+
- `actor/state.rs::wait_for_pending_writes` / `wait_for_in_flight_writes`
30+
- Classification: event-driven.
31+
- Tracked persist tasks are awaited directly; KV writes use `in_flight_writes` plus `write_completion: Notify` on decrement-to-zero.
32+
33+
- `actor/sleep.rs::wait_for_sleep_idle_window`
34+
- Classification: event-driven.
35+
- Arms `work.idle_notify` before checking HTTP request, keep-awake, internal keep-awake, and websocket callback counters.
36+
37+
- `actor/sleep.rs::wait_for_shutdown_tasks`
38+
- Classification: event-driven.
39+
- Uses `AsyncCounter::wait_zero(deadline)` for shutdown tasks and websocket callbacks, plus `prevent_sleep_notify` for the prevent-sleep flag.
40+
41+
- `actor/sleep.rs::wait_for_internal_keep_awake_idle`
42+
- Classification: event-driven.
43+
- Uses `AsyncCounter::wait_zero(deadline)`.
44+
45+
- `actor/sleep.rs::wait_for_http_requests_drained`
46+
- Classification: event-driven.
47+
- Uses the envoy `AsyncCounter::wait_zero(deadline)` after registering zero notifications on `work.idle_notify`.
48+
49+
- `actor/context.rs::wait_for_destroy_completion`
50+
- Classification: event-driven.
51+
- Uses `destroy_completion_notify` and re-checks `destroy_completed`.
52+
53+
- `actor/queue.rs::next_batch`, `wait_for_names`, and `wait_for_names_available`
54+
- Classification: event-driven.
55+
- Message waits use queue `Notify`; active wait counts are RAII-owned by `ActiveQueueWaitGuard`.
56+
57+
## Monotonic sequence / one-shot atomics
58+
59+
- `actor/state.rs` save revisions (`revision`, `save_request_revision`, `save_completed_revision`)
60+
- Classification: monotonic sequence with notify-backed awaiters.
61+
62+
- `actor/task.rs` inspector attach count
63+
- Classification: event-triggering counter.
64+
- The counter is owned by `InspectorAttachGuard`; transitions enqueue lifecycle events instead of polling.
65+
66+
- `actor/schedule.rs::local_alarm_epoch`
67+
- Classification: monotonic sequence guard.
68+
- Spawned local alarm tasks check the epoch once after the timer fires to ignore stale work.
69+
70+
- `actor/schedule.rs::driver_alarm_cancel_count`
71+
- Classification: diagnostic/test counter.
72+
- No production awaiter.
73+
74+
- `inspector/mod.rs` revision counters and active counts
75+
- Classification: snapshot/revision counters.
76+
- Subscribers are notified through listener callbacks; no async counter polling.
77+
78+
- `kv.rs` stats counters
79+
- Classification: diagnostic/test counters.
80+
- No async awaiter in production code.
81+
82+
## Non-counter sleep loops
83+
84+
- `registry.rs::wait_for_engine_health`
85+
- Classification: retry backoff.
86+
- Sleeps between external HTTP health-check attempts, not waiting on shared memory.
87+
88+
- `actor/state.rs::persist_state` and pending-save task
89+
- Classification: intentional debounce timers.
90+
- Sleeps until a configured save delay elapses, not polling a counter.
91+
92+
- `actor/schedule.rs::reschedule_local_alarm`
93+
- Classification: timer scheduling.
94+
- Sleeps until the next alarm timestamp, then checks the monotonic epoch to avoid stale dispatch.
95+
96+
- Protocol read/write loops in `registry.rs` and `sqlite.rs`
97+
- Classification: codec loops.
98+
- No async sleep or shared-state polling.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# rivetkit-napi counter-poll audit
2+
3+
Date: 2026-04-22
4+
Story: US-029
5+
6+
## Scope
7+
8+
Searched `rivetkit-typescript/packages/rivetkit-napi/src/` for:
9+
10+
- `loop { ... sleep(Duration::from_millis(_)) ... }`
11+
- `while ... { ... sleep(Duration::from_millis(_)) ... }`
12+
- `tokio::time::sleep`, `std::thread::yield_now`, and retry loops
13+
- `AtomicUsize`, `AtomicU32`, `AtomicU64`, and `AtomicBool` fields with waiters
14+
- `Mutex<usize>`, `Mutex<bool>`, and similar scalar locks
15+
- polling-shaped exports such as `poll_*`
16+
17+
## Converted polling sites
18+
19+
- `cancel_token.rs::lock_registry_for_test`
20+
- Classification before: test-only spin polling.
21+
- Problem: tests serialized access to the global cancel-token registry by spinning on an `AtomicBool` with `std::thread::yield_now()`.
22+
- Fix: replaced the spin gate with a test-only `parking_lot::Mutex<()>`, returning a real guard from `lock_registry_for_test()`.
23+
- Coverage: existing cancel-token cleanup tests still exercise the same serialized registry path.
24+
25+
## Event-driven sites
26+
27+
- `bridge_actor.rs` response waits
28+
- Classification: event-driven.
29+
- Uses per-request `oneshot` channels in `ResponseMap`; no counter or sleep-loop polling.
30+
31+
- `napi_actor_events.rs::drain_tasks`
32+
- Classification: event-driven.
33+
- Pumps already-registered tasks, then awaits `JoinSet::join_next()` until the set is empty; no timed polling interval.
34+
35+
- `napi_actor_events.rs` callback tests with `Notify`
36+
- Classification: event-driven test gates.
37+
- Uses `tokio::sync::Notify` and `oneshot` channels for deterministic ordering.
38+
39+
- Queue wait bindings in `queue.rs`
40+
- Classification: event-driven through core.
41+
- Delegates to `rivetkit-core` queue waits and optional cancellation tokens; no local counter polling.
42+
43+
## Monotonic sequence / diagnostic atomics
44+
45+
- `cancel_token.rs::NEXT_CANCEL_TOKEN_ID`
46+
- Classification: monotonic ID generator.
47+
- No waiter.
48+
49+
- `cancel_token.rs::active_token_count`
50+
- Classification: test diagnostic snapshot.
51+
- Tests read it after guarded operations complete; no async waiter or sleep-loop polls it.
52+
53+
- `actor_context.rs::next_websocket_callback_region_id`
54+
- Classification: monotonic region ID generator.
55+
- No waiter.
56+
57+
- `actor_context.rs::ready` and `started`
58+
- Classification: lifecycle flags.
59+
- Read synchronously to validate lifecycle transitions; no sleep-loop waiter.
60+
61+
- `napi_actor_events.rs` test `AtomicU64` / `AtomicBool` values
62+
- Classification: test observation flags.
63+
- Tests combine these with `oneshot`, `Notify`, or task joins; no timed polling loop waits on them.
64+
65+
## Non-counter sleep / polling-shaped sites
66+
67+
- `napi_actor_events.rs::with_timeout` and tests
68+
- Classification: timeout assertion.
69+
- Uses `tokio::time::timeout` or a bounded `select!` branch to prove a future is still pending, not to poll shared state.
70+
71+
- `napi_actor_events.rs` test `sleep(Duration::from_secs(60))`
72+
- Classification: pending-work fixture.
73+
- The sleep is intentionally cancelled by an abort token; no shared counter is polled.
74+
75+
- `queue.rs` and `schedule.rs` `Duration::from_millis(...)`
76+
- Classification: user-supplied timeout/delay conversion.
77+
- Converts JS options to core durations; no polling loop.
78+
79+
- `cancel_token.rs::poll_cancel_token`
80+
- Classification: explicit JS cancellation polling surface, not a counter waiter.
81+
- This is a public NAPI sync read used by the TS abort-signal bridge. It reads a cancellation token's state once and does not loop or wait in Rust.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# rivetkit-sqlite counter-poll audit
2+
3+
Date: 2026-04-22
4+
Story: US-028
5+
6+
## Scope
7+
8+
Searched `rivetkit-rust/packages/rivetkit-sqlite/src/` for:
9+
10+
- `loop { ... sleep(Duration::from_millis(_)) ... }`
11+
- `while ... { ... sleep(Duration::from_millis(_)) ... }`
12+
- `tokio::time::sleep`, `std::thread::sleep`
13+
- `AtomicUsize`, `AtomicU32`, `AtomicU64`, and `AtomicBool` fields with waiters
14+
- `Mutex<usize>`, `Mutex<bool>`, and similar scalar locks
15+
16+
## Converted polling sites
17+
18+
- None in this sweep.
19+
- The US-007 `MockProtocol` counter/gate fix is still present: `awaited_stage_responses` uses `AtomicUsize` plus `stage_response_awaited: Notify`, and `mirror_commit_meta` uses `AtomicBool`.
20+
- No remaining `Mutex<usize>` / `Mutex<bool>` scalar wait gates were found in `src/`.
21+
22+
## Event-driven sites
23+
24+
- `vfs.rs::MockProtocol::wait_for_stage_responses`
25+
- Classification: event-driven test waiter.
26+
- Uses `awaited_stage_responses: AtomicUsize` paired with `stage_response_awaited: Notify`.
27+
- Wait is bounded by `tokio::time::timeout(Duration::from_secs(1), ...)`.
28+
29+
- `vfs.rs::MockProtocol::commit_finalize`
30+
- Classification: event-driven test gate.
31+
- Uses `finalize_started: Notify` and `release_finalize: Notify`; no polling loop.
32+
33+
## Monotonic sequence / diagnostic atomics
34+
35+
- `vfs.rs::NEXT_STAGE_ID`, `NEXT_TEMP_AUX_ID`, and test `TEST_ID`
36+
- Classification: monotonic ID generators.
37+
- No waiter.
38+
39+
- `vfs.rs::commit_atomic_count`
40+
- Classification: diagnostic/test observation counter.
41+
- Tests read it after operations complete; no async waiter or sleep-loop polls it.
42+
43+
- `vfs.rs` performance counters (`resolve_pages_total`, `resolve_pages_cache_hits`, `resolve_pages_fetches`, `pages_fetched_total`, `prefetch_pages_total`, `commit_total`, timing totals)
44+
- Classification: metrics/snapshot counters.
45+
- Tests read snapshots after controlled operations; no wait-for-zero or wait-for-threshold loop.
46+
47+
- `vfs.rs` test `keep_reading: AtomicBool`
48+
- Classification: cross-thread control flag.
49+
- The reader thread intentionally runs SQLite reads until compaction completes; it is not waiting for the flag to become true and has no sleep-based polling interval.
50+
51+
## Non-counter sleep loops
52+
53+
- `vfs.rs::vfs_sleep`
54+
- Classification: SQLite VFS implementation callback.
55+
- Implements SQLite's `xSleep` contract by sleeping for the requested microseconds.
56+
57+
- `vfs.rs::DirectEngineHarness::open_engine`
58+
- Classification: external resource retry backoff.
59+
- Retries `RocksDbDatabaseDriver::new(...)` with a 10 ms sleep because the temporary DB directory can be briefly busy between test runs. It does not poll an in-process counter/flag/map size.
60+
61+
- `query.rs` statement loops and `vfs.rs::sqlite_step_statement`
62+
- Classification: SQLite stepping loops.
63+
- These loop over `sqlite3_step(...)` until `SQLITE_DONE` or an error; they do not sleep or poll shared state.

.agent/notes/driver-engine-static-test-order.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

.agent/notes/driver-test-fix-audit.md

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)