Skip to content

Commit

Permalink
fix: get_children should not break supervision tree integrity (#311)
Browse files Browse the repository at this point in the history
* fix: get_children should not break supervision tree integrity

* Remote take functionality and add test coverage

---------

Co-authored-by: Sean Lawlor <[email protected]>
  • Loading branch information
kanru and slawlor authored Jan 7, 2025
1 parent 1ae5d86 commit f45cdd2
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 7 deletions.
15 changes: 8 additions & 7 deletions ractor/src/actor/supervision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ impl SupervisionTree {
/// from the supervision tree since the supervisor is shutting down
/// and can't deal with superivison events anyways
pub(crate) fn terminate_all_children(&self) {
let cells = self.get_children();
let mut guard = self.children.lock().unwrap();
let cells = guard.values().cloned().collect::<Vec<_>>();
guard.clear();
// drop the guard to not deadlock on double-link
drop(guard);
for cell in cells {
cell.terminate();
cell.clear_supervisor();
Expand Down Expand Up @@ -134,13 +138,10 @@ impl SupervisionTree {
}
}

/// Return all linked children
pub(crate) fn get_children(&self) -> Vec<ActorCell> {
let mut guard = self.children.lock().unwrap();
let cells = guard.iter().map(|(_, a)| a.clone()).collect::<Vec<_>>();
guard.clear();
// drop the guard to not deadlock on double-link
drop(guard);
cells
let guard = self.children.lock().unwrap();
guard.values().cloned().collect()
}

/// Send a notification to the supervisor.
Expand Down
3 changes: 3 additions & 0 deletions ractor/src/actor/tests/supervisor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,9 @@ async fn draining_children_will_shutdown_parent_too() {
// notify the parent (supervisor) and take that down too
supervisor_ref.drain_children();

// children were not unlinked by draining them (fixed from #310)
assert!(!supervisor_ref.get_children().is_empty());

// Wait for exit
s_handle.await.unwrap();
c_handle.await.unwrap();
Expand Down

0 comments on commit f45cdd2

Please sign in to comment.