-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gracefully clean up Child on drop instead of SIGKILL? #2504
Comments
Thanks for the report! Tokio attempts to match the APIs standard library's behavior to avoid surprises for anyone coming from using those APIs. The standard library sends Tokio does expose a |
Yes but the problem is to wait for process (with timeout) to exit actually... |
Perhaps you could call |
I guess @zonyitoo prefers not creating another thread to avoid the overhead. |
If destructor is called because of Sample code: fn drop(&mut self) {
let handle = Handle::current();
handle.block_on(async {
for plugin in &mut self.plugins {
let id = plugin.id();
if let Ok(..) = plugin.await {
// ...
}
}
});
} Panics with message:
So what can we do if we couldn't use |
My suggestion was to use Rust does not support async drop, and it is not possible to block the destructor on waiting for the child. |
Yes. I think @Mygod was talking about a solution that we wanted to make: spawning a new thread and create a new If we don't block the |
If the runtime is shutting down, the spawned task would be immediately cancelled. I guess you would have to block the executor if it is shutting down. |
That's a way to work around. But I am hoping for a better way. When this |
To do something while the executor is shutting down, you have to block. You can't block with |
Yup. That's what I was doing: a busy spin. I think @Mygod is hoping for a better and cleaner solution. :( |
If you want to use different solutions depending on whether the runtime is shutting down, you could do this:
I suppose you could also detect if it was dropped outside the executor, and just do the busy spin directly. let mut spin_loop_on_kill = SpinChild::new(self); // or whatever
if let Ok(handle) = Handle::try_current() {
handle.spawn(async move {
spin_loop_on_kill.kill_with_async_waiting_and_no_spin().await;
// but if cancelled, destructor of spin child is called
});
}
// else { run destructor of `spin_loop_on_kill` here |
That is one of the solution that I was thinking about 10 minutes ago. What do you think @Mygod ? |
Well we already have a busy spin already right? I was looking for a solution that does not involve busy spin and rely on e.g. signals... 🤣 |
I'm closing this. The drop impl of |
I stumbled over this issue and had a similar problem to solve - I found it hard deriving a solution from the comments so here's what I came up with. My problem is similar to one originally described: I am writing system tests where I spawn a The binary implements handling What I first came up with was a wrapper for the Since we only need the process id for signalling we can just extract that id once we have the /// Sends a SIGTERM to the recorded process_id upon drop
///
/// Record child process id in here and keep in scope until the end of your test.
pub struct ProcessCleanup {
pub process_id: i32,
}
impl ProcessCleanup {
pub fn new(process_id: i32) -> Self {
Self { process_id }
}
}
impl Drop for ProcessCleanup {
fn drop(&mut self) {
println!(
"Cleaning up: Sending SIGTERM to process {}",
self.process_id
);
unsafe { kill(self.process_id, SIGTERM) };
}
} note: uses |
Version
master
Platform
All but mainly Android.
Subcrates
N/A
Description
Currently
Child::kill
simply sendsSIGKILL
on Unix (and similarly on Windows), which does not allow child process to perform clean ups. A more graceful solution would be to sendSIGTERM
first, and thenSIGKILL
on timeout perhaps. However, this proves to be very hard to be implement as sinceRuntime
is also dropping.Currently we have a busy spin but it would be great if tokio could support it officially.
See also: shadowsocks/shadowsocks-rust#234
The text was updated successfully, but these errors were encountered: