-
Notifications
You must be signed in to change notification settings - Fork 30
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
Make krun-server wait for child processes #34
Make krun-server wait for child processes #34
Conversation
397b12b
to
6e60d61
Compare
6e60d61
to
569f6ca
Compare
Frankly, I'm not a big fan of this approach. Here we're sacrificing joining cleaning the thread and introducing an overly complex pattern for what we really need to do. And, what's worse, we're not reaping the children until the process is going to end, meaning we're leaving zombie processes in the system. The hardest part to solve is the latter. We basically have 3 options:
I think I would favor 2, but I suspect we're going to need Tokyo sooner than later (a crate I'm looking for changing the way in which the network interface is configured requires it, but maybe there's some other option), so I'm fine with either. |
@slp I'd favour tokio. But I think the implementation will only end up being more complex, not less. (I think it's pretty much unavoidable.) Would you be okay with merging this as-is? I think it really helps with usability despite the issues you've identified above. I'll work on a follow-up PR. |
569f6ca
to
fe48ccc
Compare
It'll be more complex internally, but the code for us would be simpler thanks to tokio/async's sugar syntax.
Since we're not in a hurry to provide this to users, I think we should take our time to do it right. I might be able to work on a first implementation of tokio later this week, if you don't beat me to it ;-) |
I guess we could use
Alright. I'll start working on this |
fe48ccc
to
92fc18e
Compare
Done. 🚀 Tested working with the same scenarios. |
tokio::select! { | ||
res = &mut server_handle, if !server_died => { | ||
// If an error is received here, accepting connections from the | ||
// TCP listener failed due to non-transient errors and the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: This is a lie. We're logging and ignoring all connection errors at this time... We should continue on transient errors but bail out on non-transient errors.
Continue to accept and handle incoming connections, until the server is idle and all child processes have exited. Signed-off-by: Teoh Han Hui <[email protected]>
92fc18e
to
8eb3261
Compare
.with_context(|| format!("Failed to execute {command:?} as child process")); | ||
if let Err(err) = &res { | ||
let msg = format!("{err:?}"); | ||
stream.write_all(msg.as_bytes()).await.ok(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
write_all
is not cancellation safe. Expect Heisenbugs!
Woah, that was fast! I think we could refactor |
Working on the refactoring of EDIT: #35 |
Continue to accept and handle incoming connections, until the server is idle and all child processes have exited.
Fixes #33
Tested working with all of the scenarios mentioned in the linked issue, and confirmed that the server exits correctly once all the child processes have exited (doesn't seem to run into deadlocks).