Skip to content

Commit 46c441a

Browse files
committed
Add 'rocket::execute()'.
The function allows executing arbitrary futures, including Rocket's `launch()` future, on Rocket's async runtime. Resolves #1881.
1 parent 7908dc4 commit 46c441a

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

core/lib/src/lib.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,84 @@ pub fn async_main<R>(fut: impl std::future::Future<Output = R> + Send) -> R {
266266
let config = Config::from(Config::figment());
267267
async_run(fut, config.workers, config.shutdown.force, "rocket-worker-thread")
268268
}
269+
270+
/// Executes a `future` to completion on a new tokio-based Rocket async runtime.
271+
///
272+
/// The runtime is terminated on shutdown, and the future's resolved value is
273+
/// returned.
274+
///
275+
/// # Considerations
276+
///
277+
/// This function is a low-level mechanism intended to be used to execute the
278+
/// future returned by [`Rocket::launch()`] in a self-contained async runtime
279+
/// designed for Rocket. It runs futures in exactly the same manner as
280+
/// [`#[launch]`](crate::launch) and [`#[main]`](crate::main) do and is thus
281+
/// _never_ the preferred mechanism for running a Rocket application. _Always_
282+
/// prefer to use the [`#[launch]`](crate::launch) or [`#[main]`](crate::main)
283+
/// attributes. For example [`#[main]`](crate::main) can be used even when
284+
/// Rocket is just a small part of a bigger application:
285+
///
286+
/// ```rust,no_run
287+
/// #[rocket::main]
288+
/// async fn main() {
289+
/// # let should_start_server_in_foreground = false;
290+
/// # let should_start_server_in_background = false;
291+
/// let rocket = rocket::build();
292+
/// if should_start_server_in_foreground {
293+
/// rocket::build().launch().await;
294+
/// } else if should_start_server_in_background {
295+
/// rocket::tokio::spawn(rocket.launch());
296+
/// } else {
297+
/// // do something else
298+
/// }
299+
/// }
300+
/// ```
301+
///
302+
/// See [Rocket#launching] for more on using these attributes.
303+
///
304+
/// # Example
305+
///
306+
/// Build an instance of Rocket, launch it, and wait for shutdown:
307+
///
308+
/// ```rust,no_run
309+
/// use rocket::fairing::AdHoc;
310+
///
311+
/// let rocket = rocket::build()
312+
/// .attach(AdHoc::on_liftoff("Liftoff Printer", |_| Box::pin(async move {
313+
/// println!("Stalling liftoff for a second...");
314+
/// rocket::tokio::time::sleep(std::time::Duration::from_secs(1)).await;
315+
/// println!("And we're off!");
316+
/// })));
317+
///
318+
/// rocket::execute(rocket.launch());
319+
/// ```
320+
///
321+
/// Launch a pre-built instance of Rocket and wait for it to shutdown:
322+
///
323+
/// ```rust,no_run
324+
/// use rocket::{Rocket, Ignite, Phase, Error};
325+
///
326+
/// fn launch<P: Phase>(rocket: Rocket<P>) -> Result<Rocket<Ignite>, Error> {
327+
/// rocket::execute(rocket.launch())
328+
/// }
329+
/// ```
330+
///
331+
/// Do async work to build an instance of Rocket, launch, and wait for shutdown:
332+
///
333+
/// ```rust,no_run
334+
/// use rocket::fairing::AdHoc;
335+
///
336+
/// // This line can also be inside of the `async` block.
337+
/// let rocket = rocket::build();
338+
///
339+
/// rocket::execute(async move {
340+
/// let rocket = rocket.ignite().await?;
341+
/// let config = rocket.config();
342+
/// rocket.launch().await
343+
/// });
344+
/// ```
345+
pub fn execute<R, F>(future: F) -> R
346+
where F: std::future::Future<Output = R> + Send
347+
{
348+
async_main(future)
349+
}

core/lib/src/rocket.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ use crate::log::PaintExt;
9999
/// }
100100
/// ```
101101
///
102+
/// For extreme and rare cases in which [`#[main]`](crate::main) imposes
103+
/// obstinate restrictions, use [`rocket::execute()`](crate::execute()) to
104+
/// execute Rocket's `launch()` future.
105+
///
102106
/// * **Automatic Launching**
103107
///
104108
/// Manually progressing an instance of Rocket though its phases is only

0 commit comments

Comments
 (0)