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
|
___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());
|
let (vis, mut sig) = (&f.vis, f.sig.clone());
|
||||||
sig.ident = syn::Ident::new("main", sig.ident.span());
|
sig.ident = syn::Ident::new("main", sig.ident.span());
|
||||||
sig.output = syn::ReturnType::Default;
|
sig.output = syn::ReturnType::Default;
|
||||||
|
@ -51,7 +56,7 @@ impl EntryAttr for Launch {
|
||||||
#[allow(dead_code)] #f
|
#[allow(dead_code)] #f
|
||||||
|
|
||||||
#vis #sig {
|
#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)
|
Ok(rocket)
|
||||||
}
|
}
|
||||||
Err(rocket) => {
|
Err(rocket) => {
|
||||||
warn!("Server failed to shutdown cooperatively.");
|
warn!("Shutdown failed: outstanding background I/O.");
|
||||||
Err(Error::shutdown(rocket, None))
|
Err(Error::shutdown(rocket, None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = &mut shutdown_timer => {
|
_ = &mut shutdown_timer => {
|
||||||
warn!("Server failed to shutdown cooperatively.");
|
warn!("Shutdown failed: server executing after timeouts.");
|
||||||
return Err(Error::shutdown(rocket.clone(), None));
|
return Err(Error::shutdown(rocket.clone(), None));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue