pub struct AsyncExecutor<Q, CS> { /* private fields */ }Expand description
An asynchronous executor that can be used to run multiple async tasks. All user code runs in a single thread becasue the v5 is single threaded. Blocked tasks will stop running and wait to be unblocked while also not blocking the main thread.
§Panics
This will panic if Q::try_push ever fails.
§Example
use concurrency_traits::StdThreadFunctions;
use concurrency_traits::queue::ParkQueueStd;
use single_executor::{SleepFutureRunner, spawn_blocking, AsyncExecutorStd};
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use std::thread::sleep;
use std::time::Duration;
let executor = AsyncExecutorStd::new(ParkQueueStd::default());
let sleep_runner = Rc::new(SleepFutureRunner::new(ParkQueueStd::default()));
let sleep_runner_clone = sleep_runner.clone();
let loop_function = move ||{
let sleep_runner_clone = sleep_runner_clone.clone();
async move {
// dummy code but shows how you can await
sleep_runner_clone.sleep_for(Duration::from_millis(100)).await;
// Do stuff
}
};
executor.submit_loop(
loop_function,
Duration::from_millis(10),
sleep_runner
);
/// Dummy function
async fn get_something_from_io(){}
executor.submit(get_something_from_io());
/// Dummy blocking function
fn block_for_a_while() -> usize{
std::thread::sleep(Duration::from_millis(100));
100
}
executor.submit(async {
assert_eq!(spawn_blocking::<_, _, StdThreadFunctions>(block_for_a_while).0.await, 100);
});
// Nothing runs until run is called on the executor
let stop = Arc::new(AtomicBool::new(false));
let stop_clone = stop.clone();
thread::spawn(move || {
sleep(Duration::from_secs(1));
stop_clone.store(true, Ordering::Relaxed);
});
executor.run(stop); // Keeps running until stop is set to trueMAKE SURE NONE OF YOUR SUBMISSIONS BLOCK OR YOUR WHOLE PROGRAM WILL COME CRASHING DOWN!
Implementations§
Source§impl<Q, CS> AsyncExecutor<Q, CS>
impl<Q, CS> AsyncExecutor<Q, CS>
Sourcepub fn queue_from<T>(from: T) -> Selfwhere
Q: From<T>,
pub fn queue_from<T>(from: T) -> Selfwhere
Q: From<T>,
Creates a new executor from Q’s From<T>
implementation. Usually used for converting from an initial size.
Sourcepub fn handle(&self) -> ExecutorHandle<Q>
pub fn handle(&self) -> ExecutorHandle<Q>
Gets a handle to the executor through which tasks can be submitted.
Sourcepub fn local_handle(&self) -> LocalExecutorHandle<Q>
pub fn local_handle(&self) -> LocalExecutorHandle<Q>
Gets a handle to the executor through which tasks can be submitted. This handle may not be sent across threads but may submit !Send futures.
Sourcepub fn submit(&self, future: impl Future<Output = ()> + 'static)
pub fn submit(&self, future: impl Future<Output = ()> + 'static)
Adds a new future to the executor.
This can be called from within a future.
If this is a long running future (like a loop) then make use of sleep or
use spawn_loop instead.
Sourcepub fn submit_loop<SQ, Func, Fut>(
&self,
future_func: Func,
delay: Duration,
sleep_runner: impl Deref<Target = SleepFutureRunner<SQ, CS>> + 'static,
)where
SQ: 'static + TimeoutQueue<Item = SleepMessage<CS>> + Send + Sync,
Func: FnMut() -> Fut + 'static,
Fut: Future<Output = ()>,
pub fn submit_loop<SQ, Func, Fut>(
&self,
future_func: Func,
delay: Duration,
sleep_runner: impl Deref<Target = SleepFutureRunner<SQ, CS>> + 'static,
)where
SQ: 'static + TimeoutQueue<Item = SleepMessage<CS>> + Send + Sync,
Func: FnMut() -> Fut + 'static,
Fut: Future<Output = ()>,
Adds a new future that will be called at a set rate. Do not do a min loop inside the future, this function handles that for you.
Sourcepub fn run(&self, stop: impl Deref<Target = AtomicBool>)
pub fn run(&self, stop: impl Deref<Target = AtomicBool>)
Runs the executor, must be called or no futures will run.