mirror of
https://github.com/fafhrd91/actix-net
synced 2025-02-17 14:43:31 +01:00
spawn
should allow futures with non-unit outputs (#369)
Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
parent
4644fa41cf
commit
2b1edb95ea
@ -1,6 +1,9 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
* The `spawn` method can now resolve with non-unit outputs. [#369]
|
||||||
|
|
||||||
|
[#369]: https://github.com/actix/actix-net/pull/369
|
||||||
|
|
||||||
|
|
||||||
## 2.2.0 - 2021-03-29
|
## 2.2.0 - 2021-03-29
|
||||||
|
@ -46,7 +46,10 @@ use tokio::task::JoinHandle;
|
|||||||
// Cannot define a main macro when compiled into test harness.
|
// Cannot define a main macro when compiled into test harness.
|
||||||
// Workaround for https://github.com/rust-lang/rust/issues/62127.
|
// Workaround for https://github.com/rust-lang/rust/issues/62127.
|
||||||
#[cfg(all(feature = "macros", not(test)))]
|
#[cfg(all(feature = "macros", not(test)))]
|
||||||
pub use actix_macros::{main, test};
|
pub use actix_macros::main;
|
||||||
|
|
||||||
|
#[cfg(feature = "macros")]
|
||||||
|
pub use actix_macros::test;
|
||||||
|
|
||||||
mod arbiter;
|
mod arbiter;
|
||||||
mod runtime;
|
mod runtime;
|
||||||
@ -155,14 +158,41 @@ pub mod task {
|
|||||||
pub use tokio::task::{spawn_blocking, yield_now, JoinError, JoinHandle};
|
pub use tokio::task::{spawn_blocking, yield_now, JoinError, JoinHandle};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawns a future on the current thread.
|
/// Spawns a future on the current thread as a new task.
|
||||||
|
///
|
||||||
|
/// If not immediately awaited, the task can be cancelled using [`JoinHandle::abort`].
|
||||||
|
///
|
||||||
|
/// The provided future is spawned as a new task; therefore, panics are caught.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// Panics if Actix system is not running.
|
/// Panics if Actix system is not running.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::time::Duration;
|
||||||
|
/// # actix_rt::Runtime::new().unwrap().block_on(async {
|
||||||
|
/// // task resolves successfully
|
||||||
|
/// assert_eq!(actix_rt::spawn(async { 1 }).await.unwrap(), 1);
|
||||||
|
///
|
||||||
|
/// // task panics
|
||||||
|
/// assert!(actix_rt::spawn(async {
|
||||||
|
/// panic!("panic is caught at task boundary");
|
||||||
|
/// })
|
||||||
|
/// .await
|
||||||
|
/// .unwrap_err()
|
||||||
|
/// .is_panic());
|
||||||
|
///
|
||||||
|
/// // task is cancelled before completion
|
||||||
|
/// let handle = actix_rt::spawn(actix_rt::time::sleep(Duration::from_secs(100)));
|
||||||
|
/// handle.abort();
|
||||||
|
/// assert!(handle.await.unwrap_err().is_cancelled());
|
||||||
|
/// # });
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn spawn<Fut>(f: Fut) -> JoinHandle<()>
|
pub fn spawn<Fut>(f: Fut) -> JoinHandle<Fut::Output>
|
||||||
where
|
where
|
||||||
Fut: Future<Output = ()> + 'static,
|
Fut: Future + 'static,
|
||||||
|
Fut::Output: 'static,
|
||||||
{
|
{
|
||||||
tokio::task::spawn_local(f)
|
tokio::task::spawn_local(f)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
future::Future,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
mpsc::channel,
|
mpsc::channel,
|
||||||
@ -8,7 +9,7 @@ use std::{
|
|||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
use actix_rt::{Arbiter, System};
|
use actix_rt::{task::JoinError, Arbiter, System};
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -298,3 +299,27 @@ fn try_current_no_system() {
|
|||||||
fn try_current_with_system() {
|
fn try_current_with_system() {
|
||||||
System::new().block_on(async { assert!(System::try_current().is_some()) });
|
System::new().block_on(async { assert!(System::try_current().is_some()) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::unit_cmp)]
|
||||||
|
#[test]
|
||||||
|
fn spawn_local() {
|
||||||
|
System::new().block_on(async {
|
||||||
|
// demonstrate that spawn -> R is strictly more capable than spawn -> ()
|
||||||
|
|
||||||
|
assert_eq!(actix_rt::spawn(async {}).await.unwrap(), ());
|
||||||
|
assert_eq!(actix_rt::spawn(async { 1 }).await.unwrap(), 1);
|
||||||
|
assert!(actix_rt::spawn(async { panic!("") }).await.is_err());
|
||||||
|
|
||||||
|
actix_rt::spawn(async { tokio::time::sleep(Duration::from_millis(50)).await })
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
fn g<F: Future<Output = Result<(), JoinError>>>(_f: F) {}
|
||||||
|
g(actix_rt::spawn(async {}));
|
||||||
|
// g(actix_rt::spawn(async { 1 })); // compile err
|
||||||
|
|
||||||
|
fn h<F: Future<Output = Result<R, JoinError>>, R>(_f: F) {}
|
||||||
|
h(actix_rt::spawn(async {}));
|
||||||
|
h(actix_rt::spawn(async { 1 }));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user