mirror of https://github.com/rwf2/Rocket.git
Avoid dropping 'Error' inside '#[launch]' future.
Due to tokio-rs/tokio#4780, a panicking top-level future combined with an uncooperative background task prevents runtime shutdown. To avoid this in the case of `Rocket::launch()` returning an `Error`, which panics on drop if it isn't inspected, we return the `Result` to the caller (i.e., `main`) instead of the `block_on` future. This prevent the panic from occuring inside of the `block_on` future and so the runtime terminates even with uncooperative I/O.
This commit is contained in:
parent
c8b8b2b022
commit
30b8a77fc9
|
@ -42,6 +42,11 @@ impl EntryAttr for Launch {
|
|||
___rocket
|
||||
});
|
||||
|
||||
let launch = match f.sig.asyncness {
|
||||
Some(_) => quote_spanned!(ty.span() => async move { #rocket.launch().await }),
|
||||
None => quote_spanned!(ty.span() => #rocket.launch()),
|
||||
};
|
||||
|
||||
let (vis, mut sig) = (&f.vis, f.sig.clone());
|
||||
sig.ident = syn::Ident::new("main", sig.ident.span());
|
||||
sig.output = syn::ReturnType::Default;
|
||||
|
@ -51,7 +56,7 @@ impl EntryAttr for Launch {
|
|||
#[allow(dead_code)] #f
|
||||
|
||||
#vis #sig {
|
||||
::rocket::async_main(async move { let _res = #rocket.launch().await; })
|
||||
let _ = ::rocket::async_main(#launch);
|
||||
}
|
||||
))
|
||||
}
|
||||
|
|
|
@ -529,13 +529,13 @@ impl Rocket<Orbit> {
|
|||
Ok(rocket)
|
||||
}
|
||||
Err(rocket) => {
|
||||
warn!("Server failed to shutdown cooperatively.");
|
||||
warn!("Shutdown failed: outstanding background I/O.");
|
||||
Err(Error::shutdown(rocket, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = &mut shutdown_timer => {
|
||||
warn!("Server failed to shutdown cooperatively.");
|
||||
warn!("Shutdown failed: server executing after timeouts.");
|
||||
return Err(Error::shutdown(rocket.clone(), None));
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue