fix(pegboard-envoy): use async scc methods so actor stop cannot deadlock the envoy command stream - #5716
Conversation
|
Stack for rivet-dev/actors
Get stack: change rkrusokq |
| // A newer generation may already be serving SQL, so it is only evicted from the cache. | ||
| let close = *generation <= stopped_generation; | ||
| let (_, executor) = entry.consume(); | ||
| if close && let Some(handle) = executor.get() { |
There was a problem hiding this comment.
🟠 Medium · Close executors that finish initialization after eviction
OnceCell::get() returns None while a concurrent SQLite request is still inside get_or_try_init. That request already owns an Arc to this cell, so this callback removes the map entry without adding a handle to stopped; the initializer can then publish and use an old-generation executor after the stop command has completed. Once the request releases it, the worker is dropped through the unclean channel-close path rather than the intended close() path.
Coordinate eviction with in-progress initialization (for example, retain a close/cancellation state alongside the cell and have the initializer close a handle published after eviction), so every executor evicted by the lifecycle command is cleanly closed.
ReviewOverall this is a solid, well-motivated fix (moving Correctness —
|
…o the planner keeps index access
…ock the envoy command stream
9f9ceb1 to
f0330e1
Compare
dccfea3 to
39feccc
Compare
| // A newer generation may already be serving SQL, so it is only evicted from the cache. | ||
| let close = *generation <= stopped_generation; | ||
| let (_, executor) = entry.consume(); | ||
| if close && let Some(handle) = executor.get() { |
There was a problem hiding this comment.
🟠 Medium · Close executors that finish initialization after eviction
OnceCell::get() returns None while a concurrent SQLite request is still inside get_or_try_init. That request already owns an Arc to this cell, so this callback removes the map entry without adding a handle to stopped; the initializer can then publish and use an old-generation executor after the stop command has completed. Once the request releases it, the worker is dropped through the unclean channel-close path rather than the intended close() path.
Coordinate eviction with in-progress initialization (for example, retain a close/cancellation state alongside the cell and have the initializer close a handle published after eviction), so every executor evicted by the lifecycle command is cleanly closed.
No description provided.