Real-time compute-focused async executor with job pools, thread-local data, and priorities.
```rust use switchyard::Switchyard; use switchyard::threads::{threadinfo, singlepoolonetoone}; // Create a new switchyard with one job pool and empty thread local data let yard = Switchyard::new(1, singlepoolonetoone(threadinfo(), Some("thread-name")), ||()).unwrap();
// Spawn a task on pool 0 and priority 10 and get a JoinHandle let handle = yard.spawn(0, 10, async move { 5 + 5 }); // Spawn a lower priority task on the same pool let handle2 = yard.spawn(0, 0, async move { 2 + 2 });
// Wait on the results assert_eq!(handle.await + handle2.await, 14); ```
Switchyard is different from other existing async executors, focusing on situations where precise control of threads and execution order is needed. One such situation is using task parallelism to parallelize a compute workload.
Each task has a priority and tasks are ran in order from high priority to low priority.
rust
// Spawn task with lowest priority.
yard.spawn(0, 0, async move { /* ... */ });
// Spawn task with higher priority. If both tasks are waiting, this one will run first.
yard.spawn(0, 10, async move { /* ... */ });
Inside each yard there can be multiple (up to [MAX_POOLS
]) different "job pools". Each thread in
the pool is dedicated to a single pool. By having multiple pools, it can help prevent executor
exhaustion.
```rust // Create a yard with two job pools. Each logical core gets two threads, one per pool. let yard = Switchyard::new(2, doublepooltwotoone(thread_info(), Some("thread-name")), ||()).unwrap();
// Spawn task on pool 0. yard.spawn(0, 0, async move { /* ... / }); // Spawn task on pool 1. yard.spawn(1, 0, async move { / ... */ }); ```
Each yard has some thread local data that can be accessed using spawn_local
.
Both the thread local data and the future generated by the async function passed to spawn_local
may be !Send
and !Sync
. The future will only be resumed on the thread that created it.
If the data is Send
, then you can call access_per_thread_data
to get
a vector of mutable references to all thread's data. See it's documentation for more information.
```rust // Create yard with thread local data. The data is !Sync. let yard = Switchyard::new(1, singlepoolonetoone(thread_info(), Some("thread-name")), || Cell::new(42)).unwrap();
// Spawn task that uses thread local data. Each running thread will get their own copy. yard.spawn_local(0, 0, |data| async move { data.set(10) }); ```
1.51
Future MSRV bumps will be breaking changes.
License: MIT OR Apache-2.0 OR Zlib