How to trigger a shutdown from outside Rocket? #1880
-
I've checked the documentation for Shutdown, and it looks great, it's really clear on how to get a Shutdown handle after ignition from a rocket instance, or through a request guard. My problem is I can't really find a way to trigger a shutdown from outside Rocket, is this possible currently? I'm trying to use Rocket as part of a larger app, which handles some stuff before starting the Rocket instance (or not starting it at all), then later stopping it on demand (via an mpsc channel). I've achieved the first part by moving the entry point of the server to a child module (based on a recommendation from a previous discussion), like so: mod web_server {
#[launch]
pub fn run_rocket_server() -> Rocket<Build> {
rocket::build().attach(...)
}
}
fn main() {
// do stuff without Rocket
// launch Rocket
web_server::main();
} I've also tried to use #[rocket::main] instead of launch. My first approach was to pass the mpsc::Receiver as a parameter and use it inside Rocket to trigger a shutdown, but neither of the macro functions allow parameters in the function header. Next I've tried to return the Rocket instance after launching it, so I can get the shutdown handler outside, but neither of the functions return until the server is stopped... I can return the Rocket instance if I do not launch the server from #[rocket::main], but then I've lost the built-in tokio runtime handling of Rocket. In this case I have to spin-up an executor just to launch Rocket (after I got the shutdown handle from Rocket), which would be a hassle because my app doesn't really use anything async outside of Rocket. Any recommendations on how to tackle this problem? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
It seems like the main barrier is going to be // keeping this split out makes it easy to call 'rocket()' in tests
fn rocket() -> Rocket<Build> {
rocket::build().attach(...).mount(...)
}
/// Spawns a Rocket server and returns its Shutdown handle
async fn spawn_rocket() -> Shutdown {
let rocket = rocket().ignite().await;
let shutdown_handle = rocket.shutdown();
rocket::tokio::spawn(rocket.launch());
shutdown_handle
} The |
Beta Was this translation helpful? Give feedback.
-
I managed to get this to work, but it's not pretty. I'm just leaving this solution here for others looking for a quick hack, but I presume this is not recommended.
So I hacked around this limitation by renaming my runtime to something starting with So the bottom line: it IS possible currently to stop a Rocket instance from outside Rocket BUT it's super ugly and breaks cooperative Shutdown. |
Beta Was this translation helpful? Give feedback.
It seems like the main barrier is going to be
#[launch]
- it's designed to replace Rust's (synchronous!)fn main()
entry point, which you need for other things. You should take a look at thelaunch()
function instead; for instance, you could do something like this:The
spawn_rocket()
function can be ca…