mirror of https://github.com/fafhrd91/actix-net
99 lines
3.3 KiB
Rust
99 lines
3.3 KiB
Rust
use std::future::Future;
|
|
use std::io;
|
|
use std::time::Duration;
|
|
|
|
use tokio::{runtime, task::LocalSet};
|
|
|
|
/// A trait for construct async executor and run future on it.
|
|
///
|
|
/// A factory trait is necessary as `actix` and `actix-web` can run on multiple instances of
|
|
/// executors. Therefore the executor would be constructed multiple times
|
|
pub trait ExecFactory: Sized + Send + Sync + Unpin + 'static {
|
|
type Executor;
|
|
type Sleep: Future<Output = ()> + Send + Unpin + 'static;
|
|
|
|
fn build() -> io::Result<Self::Executor>;
|
|
|
|
/// 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 `future` has resolved either successfully or with an
|
|
/// error. The result of the future is then returned from this function
|
|
/// call.
|
|
///
|
|
/// 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
|
|
/// until `block_on` or `run` is called again.
|
|
///
|
|
/// The caller is responsible for ensuring that other spawned futures
|
|
/// complete execution by calling `block_on` or `run`.
|
|
fn block_on<F: Future>(exec: &mut Self::Executor, f: F) -> F::Output;
|
|
|
|
/// Spawn a future onto an executor without reference it.
|
|
///
|
|
/// See [module level][mod] documentation for more details.
|
|
///
|
|
/// [mod]: index.html
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// This function panics if the spawn fails. Failure occurs if the executor
|
|
/// is currently at capacity and is unable to spawn a new future.
|
|
fn spawn<F: Future<Output = ()> + 'static>(f: F);
|
|
|
|
/// Spawn a future onto an executor reference. Useful when you have direct
|
|
/// access to executor.
|
|
///
|
|
/// *. `spawn_on` is preferred when you can choose between it and `spawn`.
|
|
fn spawn_on<F: Future<Output = ()> + 'static>(exec: &mut Self::Executor, f: F);
|
|
|
|
/// Get a timeout sleep future with given duration.
|
|
fn sleep(dur: Duration) -> Self::Sleep;
|
|
}
|
|
|
|
/// Default Single-threaded tokio executor on the current thread.
|
|
///
|
|
/// See [module level][mod] documentation for more details.
|
|
///
|
|
/// [mod]: index.html
|
|
#[derive(Copy, Clone, Debug)]
|
|
pub struct ActixExec;
|
|
|
|
impl ExecFactory for ActixExec {
|
|
type Executor = (runtime::Runtime, LocalSet);
|
|
type Sleep = tokio::time::Delay;
|
|
|
|
fn build() -> io::Result<Self::Executor> {
|
|
let rt = runtime::Builder::new()
|
|
.enable_io()
|
|
.enable_time()
|
|
.basic_scheduler()
|
|
.build()?;
|
|
|
|
Ok((rt, LocalSet::new()))
|
|
}
|
|
|
|
fn block_on<F: Future>(exec: &mut Self::Executor, f: F) -> <F as Future>::Output {
|
|
let (rt, local) = exec;
|
|
|
|
rt.block_on(local.run_until(f))
|
|
}
|
|
|
|
#[inline]
|
|
fn spawn<F: Future<Output = ()> + 'static>(f: F) {
|
|
tokio::task::spawn_local(f);
|
|
}
|
|
|
|
fn spawn_on<F: Future<Output = ()> + 'static>(exec: &mut Self::Executor, f: F) {
|
|
exec.1.spawn_local(f);
|
|
}
|
|
|
|
#[inline]
|
|
fn sleep(dur: Duration) -> Self::Sleep {
|
|
tokio::time::delay_for(dur)
|
|
}
|
|
}
|