Skip to content

Commit

Permalink
document the single threaded wasm task pool (bevyengine#4571)
Browse files Browse the repository at this point in the history
# Objective

- The single threaded task pool is not documented
- This doesn't warn in CI as it's feature gated for wasm, but I'm tired of seeing the warnings when building in wasm

## Solution

- Document it
  • Loading branch information
mockersf committed Apr 24, 2022
1 parent 291ec00 commit 1cd17e9
Showing 1 changed file with 30 additions and 10 deletions.
40 changes: 30 additions & 10 deletions crates/bevy_tasks/src/single_threaded_task_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@ impl TaskPoolBuilder {
Self::default()
}

/// No op on the single threaded task pool
pub fn num_threads(self, _num_threads: usize) -> Self {
self
}

/// No op on the single threaded task pool
pub fn stack_size(self, _stack_size: usize) -> Self {
self
}

/// No op on the single threaded task pool
pub fn thread_name(self, _thread_name: String) -> Self {
self
}

/// Creates a new [`TaskPool`]
pub fn build(self) -> TaskPool {
TaskPool::new_internal()
}
Expand Down Expand Up @@ -83,16 +87,15 @@ impl TaskPool {
.collect()
}

// Spawns a static future onto the JS event loop. For now it is returning FakeTask
// instance with no-op detach method. Returning real Task is possible here, but tricky:
// future is running on JS event loop, Task is running on async_executor::LocalExecutor
// so some proxy future is needed. Moreover currently we don't have long-living
// LocalExecutor here (above `spawn` implementation creates temporary one)
// But for typical use cases it seems that current implementation should be sufficient:
// caller can spawn long-running future writing results to some channel / event queue
// and simply call detach on returned Task (like AssetServer does) - spawned future
// can write results to some channel / event queue.

/// Spawns a static future onto the JS event loop. For now it is returning FakeTask
/// instance with no-op detach method. Returning real Task is possible here, but tricky:
/// future is running on JS event loop, Task is running on async_executor::LocalExecutor
/// so some proxy future is needed. Moreover currently we don't have long-living
/// LocalExecutor here (above `spawn` implementation creates temporary one)
/// But for typical use cases it seems that current implementation should be sufficient:
/// caller can spawn long-running future writing results to some channel / event queue
/// and simply call detach on returned Task (like AssetServer does) - spawned future
/// can write results to some channel / event queue.
pub fn spawn<T>(&self, future: impl Future<Output = T> + 'static) -> FakeTask
where
T: 'static,
Expand All @@ -103,6 +106,7 @@ impl TaskPool {
FakeTask
}

/// Spawns a static future on the JS event loop. This is exactly the same as [`TaskSpool::spawn`].
pub fn spawn_local<T>(&self, future: impl Future<Output = T> + 'static) -> FakeTask
where
T: 'static,
Expand All @@ -115,9 +119,13 @@ impl TaskPool {
pub struct FakeTask;

impl FakeTask {
/// No op on the single threaded task pool
pub fn detach(self) {}
}

/// A `TaskPool` scope for running one or more non-`'static` futures.
///
/// For more information, see [`TaskPool::scope`].
#[derive(Debug)]
pub struct Scope<'scope, T> {
executor: &'scope async_executor::LocalExecutor<'scope>,
Expand All @@ -126,10 +134,22 @@ pub struct Scope<'scope, T> {
}

impl<'scope, T: Send + 'scope> Scope<'scope, T> {
/// Spawns a scoped future onto the thread-local executor. The scope *must* outlive
/// the provided future. The results of the future will be returned as a part of
/// [`TaskPool::scope`]'s return value.
///
/// On the single threaded task pool, it just calls [`Scope::spawn_local`].
///
/// For more information, see [`TaskPool::scope`].
pub fn spawn<Fut: Future<Output = T> + 'scope + Send>(&mut self, f: Fut) {
self.spawn_local(f);
}

/// Spawns a scoped future onto the thread-local executor. The scope *must* outlive
/// the provided future. The results of the future will be returned as a part of
/// [`TaskPool::scope`]'s return value.
///
/// For more information, see [`TaskPool::scope`].
pub fn spawn_local<Fut: Future<Output = T> + 'scope>(&mut self, f: Fut) {
let result = Arc::new(Mutex::new(None));
self.results.push(result.clone());
Expand Down

0 comments on commit 1cd17e9

Please sign in to comment.