From 3b5716c23e70d5427032244cb0ce4aaf543b72ac Mon Sep 17 00:00:00 2001 From: Alik Aslanyan Date: Sat, 26 Aug 2023 19:04:08 +0400 Subject: [PATCH] Add getter methods for actix_rt::Runtime and tokio::runtime::Runtime (#484) Co-authored-by: Alik Aslanyan Co-authored-by: Rob Ede --- actix-rt/CHANGES.md | 2 ++ actix-rt/src/runtime.rs | 56 +++++++++++++++++++++++++++++++++++++++++ actix-rt/src/system.rs | 35 ++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/actix-rt/CHANGES.md b/actix-rt/CHANGES.md index 0cedbaa6..ccd8a23e 100644 --- a/actix-rt/CHANGES.md +++ b/actix-rt/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Add `actix_rt::System::runtime()` method to retrieve the underlying `actix_rt::Runtime` runtime. +- Add `actix_rt::Runtime::tokio_runtime()` method to retrieve the underlying Tokio runtime. - Minimum supported Rust version (MSRV) is now 1.65. ## 2.8.0 - 2022-12-21 diff --git a/actix-rt/src/runtime.rs b/actix-rt/src/runtime.rs index 557dfcfe..55e29a77 100644 --- a/actix-rt/src/runtime.rs +++ b/actix-rt/src/runtime.rs @@ -61,6 +61,62 @@ impl Runtime { self.local.spawn_local(future) } + /// 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 + } + /// Runs the provided future, blocking the current thread until the future completes. /// /// This function can be used to synchronously block the current thread until the provided diff --git a/actix-rt/src/system.rs b/actix-rt/src/system.rs index 7423a01e..8ff02c83 100644 --- a/actix-rt/src/system.rs +++ b/actix-rt/src/system.rs @@ -203,6 +203,41 @@ impl SystemRunner { .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) } + /// Retrieves a reference to the underlying Actix runtime associated with this SystemRunner instance. + /// + /// The Actix runtime is responsible for managing the event loop for an Actix system and executing asynchronous tasks. + /// This method provides access to the runtime, allowing direct interaction with its features. + /// + /// In a typical use case, you might need to share the same runtime between different + /// parts of your project. For example, some components might require a [`actix_rt::Runtime`] to spawn tasks on + /// the same runtime. + /// + /// # Example + /// + /// ``` + /// let system_runner = actix_rt::System::new(); + /// let actix_runtime = system_runner.runtime(); + /// + /// // Use the runtime to spawn an async task or perform other operations + /// ``` + /// + /// Read more in the documentation for [`actix_rt::Runtime`] + /// + /// # Returns + /// + /// An immutable reference to the [`actix_rt::Runtime`] instance associated with this + /// [`actix_rt::SystemRunner`] instance. + /// + /// # Note + /// + /// While this method provides an immutable reference to the Actix runtime, which is safe to share across threads, + /// be aware that spawning blocking tasks on the Actix runtime could potentially impact system performance. + /// This is because the Actix runtime is responsible for driving the system, + /// and blocking tasks could delay other tasks in the run loop. + pub fn runtime(&self) -> &crate::runtime::Runtime { + &self.rt + } + /// Runs the provided future, blocking the current thread until the future completes. #[track_caller] #[inline]