-
Notifications
You must be signed in to change notification settings - Fork 373
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
Handle ctrl+c to gracefully shutdown the server(s) #1613
Conversation
I tested |
crates/rerun/src/web_viewer.rs
Outdated
|
||
let web_server_join_handle = tokio_rt.spawn(async move { | ||
// This is the server which the web viewer will talk to: | ||
let ws_server = re_ws_comms::Server::new(re_ws_comms::DEFAULT_WS_SERVER_PORT) | ||
.await | ||
.unwrap(); | ||
let ws_server_handle = tokio::spawn(ws_server.listen(rerun_rx)); // TODO(emilk): use tokio_rt ? | ||
let ws_server_handle = tokio::spawn(ws_server.listen(rerun_rx, shutdown_rx_ws_server)); // TODO(emilk): use tokio_rt ? |
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.
Do we really need this channel for the ws server? Doesn't calling self.web_server_join_handle.abort()
(as we do in drop
) already work?
That's one of the advantages of async tasks in general: they are easy to cancel (just drop their handles).
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.
Hm. I could try ripping out the channel again from both servers and go with abort
. Wonder if that is the same really as the shutdown I'm doing now.
I'd suggest not going there and unify as suggested above by using shutdown_tx
on Drop
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.
dropping a handle does not cancel a task though, one needs to call abort
on it explicitly? (only found this old thread where that decision was made, maybe has changed since then tokio-rs/tokio#1830 (comment))
Also do all tasks implement proper abort? The channel setup here follows tokio's recommendation on how to deal with ctrl+c
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.
I thought abort
would work on any async
task, since it simply stops the future from being polled. I don't understand why tokio would recommend something else.
Where is this recommendation?
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.
https://tokio.rs/tokio/topics/shutdown
let next_frame = tokio::select! {
res = self.connection.read_frame() => res?,
_ = self.shutdown.recv() => {
// If a shutdown signal is received, return from `run`.
// This will result in the task terminating.
return Ok(());
}
};
Maybe this is a bit too much out of context we're dealing with more specific tasks after all. Furthermore, most of this does boil down to an abort
I reckon. The reason I ended up here was not exhaustive research and consideration of what we have, but rather seeing that example and going with it, discovering stuff in the process.
That said, I'm actually quite happy with this solution here since it gives us a single super easy entry point for signaling shut down which also makes it easy to work with hyper's with_graceful_shutdown
|
oof this has bigger ramifications. |
…l shutdown mechanism Had to move setup_ctrl_c_handler back to `rerun` because of this
works now. Tested all |
more issues! I didn't try |
…n't create a new runtime if there is one already. Gracefully wait on ctrl+c instead of sleeping for `RerunArgs` entrypoint
that one is passing now as well! Changes got a lot bigger, but I do think it's better - admittedly still learning all these tokio things though; got quite far 😄 |
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.
Looks great 👏👏👏
@@ -74,6 +74,18 @@ impl RerunArgs { | |||
default_enabled: bool, | |||
run: impl FnOnce(Session) + Send + 'static, | |||
) -> anyhow::Result<()> { | |||
// Ensure we have a running tokio runtime. |
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.
very nice
Found a problem after merge:
Reverting in #1632 |
I think the solution to the above problem would be to hand down …though I am not a big fan of how tokio is infecting every part of the codebase :/ |
Fixes
Tried to use tokio's ctrl-c detection but ran into issues with it, so used the ctrlc crate we already depend on and got it working nicely with that.
Tested ctrl'c'ing with:
Serving
cargo run -p rerun --features web_viewer -- ../api_demo.rrd --web-viewer
cargo run -p rerun --features web_viewer -- --web-viewer
cargo run -p re_web_viewer_server
cargo run -p api_demo -- --serve
python ./examples/python/api_demo/main.py --serve
python3 -m rerun --web-viewer ../objectron.rrd
Not serving, just to see if something else broke
python ./examples/python/tracking_hf_opencv/main.py
cargo run -p api_demo
Checklist