feat(rivetkit): isolate includeState transaction reads with a committed snapshot - #5638
Conversation
|
Stack for rivet-dev/actors
Get stack: change snxxvxko |
|
🚅 Deployed to the actors-pr-5638 environment in rivet-frontend
|
ReviewThis is a well-scoped fix: Bug: connection state is not covered by the isolation fix
Since Minor
Nice fix on the core actor-state race; the connection-state gap is worth closing in the same PR since the updated doc comment currently overclaims the guarantee. |
…ed snapshot An includeState state transaction mutated actor state in place, so a concurrent action reading state mid-transaction observed the owner's uncommitted writes (a dirty read); the writes only reverted on rollback. That gave atomic commit but not read isolation. Take a structured-clone snapshot of the committed state when the transaction opens. The transaction owner keeps mutating the live state (so commit/rollback, onStateChange, and retained-proxy semantics are unchanged), but every non-owner context — actions, runtime save ticks, the inspector, sleep saves — reads the snapshot instead. Concurrent readers therefore observe only committed values until the owner commits, and a save driven from a non-owner context can no longer serialize uncommitted state. The snapshot is torn down on transaction exit. Note: the driver-suite state-transaction tests require the native engine and could not be run in this environment (they fail identically on unmodified main); validated by typecheck, the mock-provider unit tests, and review.
805dc7a to
8b21384
Compare
An includeState state transaction mutated actor state in place, so a
concurrent action reading state mid-transaction observed the owner's
uncommitted writes (a dirty read); the writes only reverted on rollback. That
gave atomic commit but not read isolation.
Take a structured-clone snapshot of the committed state when the transaction
opens. The transaction owner keeps mutating the live state (so commit/rollback,
onStateChange, and retained-proxy semantics are unchanged), but every non-owner
context — actions, runtime save ticks, the inspector, sleep saves — reads the
snapshot instead. Concurrent readers therefore observe only committed values
until the owner commits, and a save driven from a non-owner context can no
longer serialize uncommitted state. The snapshot is torn down on transaction
exit.
Note: the driver-suite state-transaction tests require the native engine and
could not be run in this environment (they fail identically on unmodified
main); validated by typecheck, the mock-provider unit tests, and review.