fix(rivetkit): minor sleep-cleanup follow-ups#4761
fix(rivetkit): minor sleep-cleanup follow-ups#4761NathanFlurry wants to merge 1 commit intosleep-cleanup/15-stale-prevent-sleep-refsfrom
Conversation
Code Review: fix(rivetkit): minor sleep-cleanup follow-upsOverviewThis PR contains four targeted cleanups to the sleep/destroy lifecycle:
`context.rs` — Consolidation via `mark_destroy_requested()`Good change. The refactoring correctly consolidates the inline sequence (`cancel_sleep_timer`, `flush_on_shutdown`, `destroy_completed.store(false)`, `abort_signal.cancel()`) into the shared `mark_destroy_requested()` helper (verified at L465-470: it contains all four operations). This eliminates a drift risk. Minor comment nit: The comment says "`destroy_requested` is already true from the swap above; the redundant `store(true)` inside is harmless." However, `mark_destroy_requested()` stores `false` into `destroy_completed`, not `true`. The "store(true)" in the comment refers to the `destroy_requested` flag — technically accurate but potentially confusing for a reader who looks at the implementation and sees a `store(false)` call. Consider clarifying: "`destroy_requested` is already true from the check above; `mark_destroy_requested` will set it again, which is harmless." `sleep.rs` — Test improvementsCancellation-propagation test (`shutdown_deadline_token_aborts_select_awaiting_task`): Strong improvement. The old test only checked `token.is_cancelled()`, which any trivially correct implementation satisfies. The new test spawns a real `tokio::select!` task that blocks on `pending::<()>()`, meaning it only exits when cancellation propagates to the cloned token. The `yield_now().await` pre-check is a good guard against false positives. Exhaustive match in `set_prevent_sleep_is_a_deprecated_noop`: The compile-time protection is clever — adding a new `CanSleep` variant without updating this match will be a build error rather than a silent pass. However, there is a test quality regression: the original code asserted `can_sleep().await == CanSleep::Yes` (verifying the specific expected behavior), while the new exhaustive match accepts any return value. The test no longer verifies that `set_prevent_sleep(true)` has no effect on the outcome. Consider combining both goals: ```rust `task.rs` — Timeout cap fixGenuine bug fix. An actor with a `sleepGracePeriod` longer than `SERIALIZE_STATE_SHUTDOWN_SANITY_CAP` (15s) would silently cap its `serializeState` timeout at 15s even though the user allocated more budget, leading to empty-delta saves within the user's own grace window. The `.max()` fix is correct. Improved log message: Adding `actor_id` and `cap_ms` to the timeout error is a good observability improvement consistent with the structured logging conventions. One concern: The cap is now raised for all stop reasons (destroy/stop, not only sleep) since `effective_sleep_grace_period()` is read unconditionally. If a destroy is triggered and the actor has a large `sleepGracePeriod`, the destroy path inherits the larger serialization timeout. This may be intentional (large state writes need the budget regardless of stop reason), but worth explicitly verifying — destroy already has its own independent timeout (`on_destroy_timeout`) that is separate from the sleep grace period. `native.ts` — Destroy ordering fixCorrect fix. Calling `callNativeSync(() => this.#ctx.destroy())` before `markNativeDestroyRequested(ctx)` ensures that if the native destroy throws (`actor/starting` or `actor/stopping`), the `destroyCompletion` promise is never created and `destroyGate` is not left with stale state. The prior ordering could leak an unresolved Promise if the native call threw synchronously. The comment is clear and the reasoning is sound. Summary
Overall this is a solid set of targeted cleanups. The main actionable items are restoring the `CanSleep::Yes` assertion in the prevent-sleep test, and confirming the destroy timeout cap semantics are intentional. |
2893e31 to
8f8ecec
Compare
Preview packages published to npmInstall with: npm install rivetkit@pr-4761All packages published as Engine binary is shipped via Docker images: docker pull rivetdev/engine:slim-c7ed968
docker pull rivetdev/engine:full-c7ed968Individual packagesnpm install rivetkit@pr-4761
npm install @rivetkit/react@pr-4761
npm install @rivetkit/rivetkit-napi@pr-4761
npm install @rivetkit/workflow-engine@pr-4761 |

Description
Please include a summary of the changes and the related issue. Please also include relevant motivation and context.
Type of change
How Has This Been Tested?
Please describe the tests that you ran to verify your changes.
Checklist: