1
0
mirror of https://github.com/fafhrd91/actix-net synced 2025-01-31 13:52:08 +01:00
actix-net/actix-rt/src/runtime.rs

150 lines
4.9 KiB
Rust
Raw Normal View History

2021-01-26 09:46:14 +00:00
use std::{future::Future, io};
2018-12-09 19:55:40 -08:00
2021-01-26 09:46:14 +00:00
use tokio::task::{JoinHandle, LocalSet};
2021-02-03 10:25:31 +00:00
/// A Tokio-based runtime proxy.
2018-12-09 19:55:40 -08:00
///
/// All spawned futures will be executed on the current thread. Therefore, there is no `Send` bound
/// on submitted futures.
2018-12-09 19:55:40 -08:00
#[derive(Debug)]
pub struct Runtime {
2019-12-05 16:40:24 +06:00
local: LocalSet,
2021-01-26 09:46:14 +00:00
rt: tokio::runtime::Runtime,
2018-12-09 19:55:40 -08:00
}
2021-02-03 10:25:31 +00:00
pub(crate) fn default_tokio_runtime() -> io::Result<tokio::runtime::Runtime> {
tokio::runtime::Builder::new_current_thread()
.enable_io()
.enable_time()
.build()
}
2018-12-09 19:55:40 -08:00
impl Runtime {
/// Returns a new runtime initialized with default configuration values.
2021-01-26 09:46:14 +00:00
#[allow(clippy::new_ret_no_self)]
2021-02-03 10:25:31 +00:00
pub fn new() -> io::Result<Self> {
let rt = default_tokio_runtime()?;
2018-12-09 19:55:40 -08:00
2019-12-05 16:40:24 +06:00
Ok(Runtime {
rt,
local: LocalSet::new(),
})
2018-12-09 19:55:40 -08:00
}
2021-01-26 09:46:14 +00:00
/// Offload a future onto the single-threaded runtime.
2018-12-09 19:55:40 -08:00
///
2021-01-26 09:46:14 +00:00
/// The returned join handle can be used to await the future's result.
2018-12-09 19:55:40 -08:00
///
2021-01-26 09:46:14 +00:00
/// See [crate root][crate] documentation for more details.
2018-12-09 19:55:40 -08:00
///
/// # Examples
2021-01-26 09:46:14 +00:00
/// ```
/// let rt = actix_rt::Runtime::new().unwrap();
2018-12-09 19:55:40 -08:00
///
/// // Spawn a future onto the runtime
2021-01-26 09:46:14 +00:00
/// let handle = rt.spawn(async {
2018-12-09 19:55:40 -08:00
/// println!("running on the runtime");
2021-01-26 09:46:14 +00:00
/// 42
/// });
///
/// assert_eq!(rt.block_on(handle).unwrap(), 42);
2018-12-09 19:55:40 -08:00
/// ```
///
/// # Panics
2021-01-26 09:46:14 +00:00
/// This function panics if the spawn fails. Failure occurs if the executor is currently at
/// capacity and is unable to spawn a new future.
#[track_caller]
2021-01-26 09:46:14 +00:00
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
2018-12-09 19:55:40 -08:00
where
2021-01-26 09:46:14 +00:00
F: Future + 'static,
2018-12-09 19:55:40 -08:00
{
2021-01-26 09:46:14 +00:00
self.local.spawn_local(future)
2018-12-09 19:55:40 -08:00
}
/// Retrieves a reference to the underlying Tokio runtime associated with this instance.
///
/// The Tokio runtime is responsible for executing asynchronous tasks and managing
/// the event loop for an asynchronous Rust program. This method allows accessing
/// the runtime to interact with its features directly.
///
/// In a typical use case, you might need to share the same runtime between different
/// modules of your project. For example, a module might require a `tokio::runtime::Handle`
/// to spawn tasks on the same runtime, or the runtime itself to configure more complex
/// behaviours.
///
/// # Example
///
/// ```
/// use actix_rt::Runtime;
///
/// mod module_a {
/// pub fn do_something(handle: tokio::runtime::Handle) {
/// handle.spawn(async {
/// // Some asynchronous task here
/// });
/// }
/// }
///
/// mod module_b {
/// pub fn do_something_else(rt: &tokio::runtime::Runtime) {
/// rt.spawn(async {
/// // Another asynchronous task here
/// });
/// }
/// }
///
/// let actix_runtime = actix_rt::Runtime::new().unwrap();
/// let tokio_runtime = actix_runtime.tokio_runtime();
///
/// let handle = tokio_runtime.handle().clone();
///
/// module_a::do_something(handle);
/// module_b::do_something_else(tokio_runtime);
/// ```
///
/// # Returns
///
/// An immutable reference to the `tokio::runtime::Runtime` instance associated with this
/// `Runtime` instance.
///
/// # Note
///
/// While this method provides an immutable reference to the Tokio runtime, which is safe to share across threads,
/// be aware that spawning blocking tasks on the Tokio runtime could potentially impact the execution
/// of the Actix runtime. This is because Tokio is responsible for driving the Actix system,
/// and blocking tasks could delay or deadlock other tasks in run loop.
pub fn tokio_runtime(&self) -> &tokio::runtime::Runtime {
&self.rt
}
2021-01-26 09:46:14 +00:00
/// Runs the provided future, blocking the current thread until the future completes.
2018-12-09 19:55:40 -08:00
///
2021-01-26 09:46:14 +00:00
/// This function can be used to synchronously block the current thread until the provided
/// `future` has resolved either successfully or with an error. The result of the future is
/// then returned from this function call.
2018-12-09 19:55:40 -08:00
///
2021-01-26 09:46:14 +00:00
/// Note that this function will also execute any spawned futures on the current thread, but
/// will not block until these other spawned futures have completed. Once the function returns,
/// any uncompleted futures remain pending in the `Runtime` instance. These futures will not run
2018-12-09 19:55:40 -08:00
/// until `block_on` or `run` is called again.
///
2021-01-26 09:46:14 +00:00
/// The caller is responsible for ensuring that other spawned futures complete execution by
/// calling `block_on` or `run`.
#[track_caller]
pub fn block_on<F>(&self, f: F) -> F::Output
2018-12-09 19:55:40 -08:00
where
F: Future,
2018-12-09 19:55:40 -08:00
{
self.local.block_on(&self.rt, f)
2018-12-09 19:55:40 -08:00
}
}
2021-02-03 10:25:31 +00:00
impl From<tokio::runtime::Runtime> for Runtime {
fn from(rt: tokio::runtime::Runtime) -> Self {
Self {
local: LocalSet::new(),
rt,
}
}
}