Skip to content

[feat] Add kill tree for sidecar #14360

@elibroftw

Description

@elibroftw

Describe the problem

My sidecar is a PyInstaller Python app. Because it's a single file how it works is a PyInstaller bootloader creates a child process for my app, and thus the "app" works. There are two issues right now.

  1. When I exit the Tauri app, the sidecar does not get killed.
  2. When I manually kill the child, its child process is still alive

Describe the solution you'd like

Well I'd rather just that the Tauri sidecar cleans up for me. However, if that's not possible, I'd like a kill_all method like there used to be?

Alternatives considered

struct MyStruct {
fn kill(&mut self) {
    if let Some(child) = self.child.take() {
           kill_process_tree(child.pid()).unwrap()
    }
  }
}


fn kill_process_tree(pid: u32) -> Result<(), String> {
    let mut system = System::new_all();
    system.refresh_all();

    let root_pid = Pid::from_u32(pid);
    let mut to_kill = HashSet::new();

    // Collect all descendant PIDs
    collect_descendants(&system, root_pid, &mut to_kill);
    to_kill.insert(root_pid);

    // Kill all processes (children first, then parent)
    for &pid in &to_kill {
        if let Some(process) = system.process(pid) {
            process.kill_with(Signal::Kill);
        }
    }

    Ok(())
}

fn collect_descendants(system: &System, pid: Pid, descendants: &mut HashSet<Pid>) {
    for (child_pid, process) in system.processes() {
        if let Some(parent_pid) = process.parent() {
            if parent_pid == pid {
                descendants.insert(*child_pid);
                collect_descendants(system, *child_pid, descendants);
            }
        }
    }
}

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions