AsyncExecutor

Struct AsyncExecutor 

Source
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 true

MAKE SURE NONE OF YOUR SUBMISSIONS BLOCK OR YOUR WHOLE PROGRAM WILL COME CRASHING DOWN!

Implementations§

Source§

impl<Q, CS> AsyncExecutor<Q, CS>
where Q: 'static + TimeoutQueue<Item = AsyncTask> + Send + Sync, CS: ConcurrentSystem<()>,

Source

pub fn new(task_queue: Q) -> Self

Creates a new executor from a given queue

Source

pub fn queue_from<T>(from: T) -> Self
where Q: From<T>,

Creates a new executor from Q’s From<T> implementation. Usually used for converting from an initial size.

Source

pub fn handle(&self) -> ExecutorHandle<Q>

Gets a handle to the executor through which tasks can be submitted.

Source

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.

Source

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.

Source

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.

Source

pub fn run(&self, stop: impl Deref<Target = AtomicBool>)

Runs the executor, must be called or no futures will run.

Trait Implementations§

Source§

impl<Q: Debug, CS: Debug> Debug for AsyncExecutor<Q, CS>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<Q, CS> Freeze for AsyncExecutor<Q, CS>

§

impl<Q, CS> RefUnwindSafe for AsyncExecutor<Q, CS>
where Q: RefUnwindSafe,

§

impl<Q, CS> !Send for AsyncExecutor<Q, CS>

§

impl<Q, CS> !Sync for AsyncExecutor<Q, CS>

§

impl<Q, CS> Unpin for AsyncExecutor<Q, CS>

§

impl<Q, CS> UnwindSafe for AsyncExecutor<Q, CS>
where Q: RefUnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.