Skip to main content

SomeExecutor

Trait SomeExecutor 

Source
pub trait SomeExecutor:
    Send
    + Sync
    + Debug {
    type ExecutorNotifier: ExecutorNotified + Send;

    // Required methods
    fn spawn<F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>(
        &mut self,
        task: Task<F, Notifier>,
    ) -> impl Observer<Value = F::Output> + Send
       where Self: Sized,
             F::Output: Send + Unpin;
    fn spawn_async<'s, F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>(
        &'s mut self,
        task: Task<F, Notifier>,
    ) -> impl Future<Output = impl Observer<Value = F::Output>> + Send + 's
       where Self: Sized,
             F::Output: Send + Unpin;
    fn spawn_objsafe(&mut self, task: ObjSafeTask) -> BoxedSendObserver;
    fn spawn_objsafe_async<'s>(
        &'s mut self,
        task: ObjSafeTask,
    ) -> BoxedSendObserverFuture<'s>;
    fn clone_box(&self) -> Box<DynExecutor>;
    fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier>;
}
Expand description

A trait targeting ‘some’ executor.

Code targeting this trait can spawn tasks on an executor without knowing which executor it is. This is the core abstraction that allows writing executor-agnostic async code.

If possible, use the SomeExecutorExt trait instead for a more ergonomic API. This trait is primarily useful when you need an object-safe trait for dynamic dispatch.

§Example

let future = Box::new(async { Box::new(42) as Box<dyn Any + Send> });
let task = Task::new_objsafe(
    "example".to_string(),
    future,
    Default::default(),
    None
);
let observer = exec.spawn_objsafe(task);
// Can track task completion via observer

Required Associated Types§

Source

type ExecutorNotifier: ExecutorNotified + Send

§Design notes

I think we want ExecutorNotified to imply Send (or at least in the case of SomeExecutor trait). We want to permit the notifier to be sent into e.g. the future, running on a threadpool for example.

Required Methods§

Source

fn spawn<F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>( &mut self, task: Task<F, Notifier>, ) -> impl Observer<Value = F::Output> + Send
where Self: Sized, F::Output: Send + Unpin,

Spawns a future onto the runtime.

§Parameters
  • task: The task to spawn.
§Note

Send and 'static are generally required to move the future onto a new thread.

§Implementation notes

Implementations should generally ensure that a dlog-context is available to the future.

For details on why F::Output is Unpin, see the comment on observer::TypedObserver.

Source

fn spawn_async<'s, F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>( &'s mut self, task: Task<F, Notifier>, ) -> impl Future<Output = impl Observer<Value = F::Output>> + Send + 's
where Self: Sized, F::Output: Send + Unpin,

Spawns a future onto the runtime.

Like Self::spawn, but some implementors may have a fast path for the async context.

§Implementation notes

For details on why F::Output is Unpin, see the comment on observer::TypedObserver.

Source

fn spawn_objsafe(&mut self, task: ObjSafeTask) -> BoxedSendObserver

Spawns a future onto the runtime.

§Note

This differs from SomeExecutor::spawn in that we take a boxed future, since we can’t have generic fn. Implementations probably pin this with Box::into_pin.

Source

fn spawn_objsafe_async<'s>( &'s mut self, task: ObjSafeTask, ) -> BoxedSendObserverFuture<'s>

Spawns a future onto the runtime.

§Note

This differs from SomeExecutor::spawn in that we take a boxed future, since we can’t have generic fn. Implementations probably pin this with Box::into_pin.

Source

fn clone_box(&self) -> Box<DynExecutor>

Clones the executor.

The returned value will spawn tasks onto the same executor.

Source

fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier>

Produces an executor notifier.

Trait Implementations§

Source§

impl<UnderlyingNotifier: ExecutorNotified + Send> SomeExecutor for Box<dyn SomeExecutor<ExecutorNotifier = UnderlyingNotifier>>

Implementation of SomeExecutor for boxed executor trait objects.

This implementation enables Box<dyn SomeExecutor> to act as an executor itself, providing the crucial type erasure pattern that allows executors to be stored and used polymorphically.

§How It Works

When you spawn a task on a boxed executor:

  1. The concrete future type is converted to a type-erased version using into_objsafe()
  2. The type-erased task is spawned on the underlying executor
  3. A DowncastObserver is returned that will convert results back to the original type

§Examples

let mut executor: Box<dyn SomeExecutor<ExecutorNotifier = Infallible>> = todo!();

// Spawn a typed future
let task = Task::without_notifications(
    "hello-task".to_string(),
    Configuration::default(),
    async { "hello".to_string() }
);
Source§

fn spawn<F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>( &mut self, task: Task<F, Notifier>, ) -> impl Observer<Value = F::Output>
where Self: Sized, F::Output: Send + Unpin,

Spawns a future onto the underlying executor with automatic type erasure and recovery.

This method handles the type erasure process transparently, converting the typed future into a type-erased version for the underlying executor, then wrapping the returned observer to restore type information.

Source§

async fn spawn_async<F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>( &mut self, task: Task<F, Notifier>, ) -> impl Observer<Value = F::Output>
where Self: Sized, F::Output: Send + Unpin,

Asynchronously spawns a future onto the underlying executor.

Similar to spawn, but allows the spawning process itself to be asynchronous.

Source§

fn spawn_objsafe( &mut self, task: Task<Pin<Box<dyn Future<Output = Box<dyn Any + Send + 'static>> + Send + 'static>>, Box<dyn ObserverNotified<dyn Any + Send> + Send>>, ) -> Box<dyn Observer<Value = Box<dyn Any + Send>, Output = FinishedObservation<Box<dyn Any + Send>>> + Send>

Spawns an already type-erased task.

This is the object-safe method that works with type-erased futures directly. User code typically doesn’t call this; it’s used internally by the typed spawn methods.

Source§

fn spawn_objsafe_async<'s>( &'s mut self, task: Task<Pin<Box<dyn Future<Output = Box<dyn Any + Send + 'static>> + Send + 'static>>, Box<dyn ObserverNotified<dyn Any + Send> + Send>>, ) -> Box<dyn Future<Output = Box<dyn Observer<Value = Box<dyn Any + Send>, Output = FinishedObservation<Box<dyn Any + Send>>> + Send>> + 's>

Asynchronously spawns an already type-erased task.

The async version of spawn_objsafe for executors that need async initialization.

Source§

fn clone_box(&self) -> Box<DynExecutor>

Creates a boxed clone of the executor.

This allows the boxed executor to be cloned while preserving the type erasure.

Source§

fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier>

Gets a notifier for executor-level events, if supported.

Returns a type-erased notifier that can be used to wake the executor.

Source§

type ExecutorNotifier = Box<dyn ExecutorNotified + Send>

Design notes Read more

Implementations on Foreign Types§

Source§

impl<UnderlyingNotifier: ExecutorNotified + Send> SomeExecutor for Box<dyn SomeExecutor<ExecutorNotifier = UnderlyingNotifier>>

Implementation of SomeExecutor for boxed executor trait objects.

This implementation enables Box<dyn SomeExecutor> to act as an executor itself, providing the crucial type erasure pattern that allows executors to be stored and used polymorphically.

§How It Works

When you spawn a task on a boxed executor:

  1. The concrete future type is converted to a type-erased version using into_objsafe()
  2. The type-erased task is spawned on the underlying executor
  3. A DowncastObserver is returned that will convert results back to the original type

§Examples

let mut executor: Box<dyn SomeExecutor<ExecutorNotifier = Infallible>> = todo!();

// Spawn a typed future
let task = Task::without_notifications(
    "hello-task".to_string(),
    Configuration::default(),
    async { "hello".to_string() }
);
Source§

fn spawn<F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>( &mut self, task: Task<F, Notifier>, ) -> impl Observer<Value = F::Output>
where Self: Sized, F::Output: Send + Unpin,

Spawns a future onto the underlying executor with automatic type erasure and recovery.

This method handles the type erasure process transparently, converting the typed future into a type-erased version for the underlying executor, then wrapping the returned observer to restore type information.

Source§

async fn spawn_async<F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>( &mut self, task: Task<F, Notifier>, ) -> impl Observer<Value = F::Output>
where Self: Sized, F::Output: Send + Unpin,

Asynchronously spawns a future onto the underlying executor.

Similar to spawn, but allows the spawning process itself to be asynchronous.

Source§

fn spawn_objsafe( &mut self, task: Task<Pin<Box<dyn Future<Output = Box<dyn Any + Send + 'static>> + Send + 'static>>, Box<dyn ObserverNotified<dyn Any + Send> + Send>>, ) -> Box<dyn Observer<Value = Box<dyn Any + Send>, Output = FinishedObservation<Box<dyn Any + Send>>> + Send>

Spawns an already type-erased task.

This is the object-safe method that works with type-erased futures directly. User code typically doesn’t call this; it’s used internally by the typed spawn methods.

Source§

fn spawn_objsafe_async<'s>( &'s mut self, task: Task<Pin<Box<dyn Future<Output = Box<dyn Any + Send + 'static>> + Send + 'static>>, Box<dyn ObserverNotified<dyn Any + Send> + Send>>, ) -> Box<dyn Future<Output = Box<dyn Observer<Value = Box<dyn Any + Send>, Output = FinishedObservation<Box<dyn Any + Send>>> + Send>> + 's>

Asynchronously spawns an already type-erased task.

The async version of spawn_objsafe for executors that need async initialization.

Source§

fn clone_box(&self) -> Box<DynExecutor>

Creates a boxed clone of the executor.

This allows the boxed executor to be cloned while preserving the type erasure.

Source§

fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier>

Gets a notifier for executor-level events, if supported.

Returns a type-erased notifier that can be used to wake the executor.

Source§

type ExecutorNotifier = Box<dyn ExecutorNotified + Send>

Implementors§