7 releases
Uses new Rust 2024
| new 0.3.0 | May 21, 2026 |
|---|---|
| 0.2.0 | May 2, 2026 |
| 0.1.4 | Jul 21, 2025 |
| 0.1.3 | May 8, 2025 |
#90 in Asynchronous
744 downloads per month
Used in 146 crates
(51 directly)
240KB
4.5K
SLoC
MoosicBox Async
Async runtime abstraction and utilities for MoosicBox applications.
Overview
The MoosicBox Async package provides:
- Runtime Abstraction: Generic async runtime interface
- Multi-Backend: Support for Tokio and simulation runtimes
- Builder Pattern: Flexible runtime configuration
- Feature-Gated: Modular async functionality
- Thread Management: Thread ID tracking and management
Features
Runtime Abstraction
- GenericRuntime: Common interface for all async runtimes
- Runtime Builder: Configurable runtime construction
- Backend Selection: Choose between Tokio and simulation runtimes
- Future Support: Standard Future trait integration
Backend Support
- Tokio: Production async runtime
- Simulator: Deterministic simulation runtime for testing
- Feature-Gated: Enable only needed backends
Async Utilities
- Thread ID: Unique thread identification
- Task Management: Task spawning and joining
- IO Operations: Async I/O primitives (feature-gated)
- Synchronization: Async synchronization primitives (feature-gated)
- Timers: Async timing utilities (feature-gated)
Installation
Add this to your Cargo.toml:
[dependencies]
switchy_async = "0.1.4"
With Tokio backend features:
[dependencies]
switchy_async = { version = "0.1.4", default-features = false, features = ["tokio", "rt-multi-thread", "io", "sync", "time", "macros"] }
For testing with simulation:
[dependencies]
switchy_async = { version = "0.1.4", default-features = false, features = ["simulator", "macros"] }
Usage
Runtime Creation
use switchy_async::{Builder, GenericRuntime};
// Create runtime with default settings (current-thread)
let runtime = Builder::new().build()?;
// Use generic runtime interface
runtime.block_on(async {
println!("Hello from async runtime!");
});
// Wait for runtime to complete
runtime.wait()?;
// With multi-threaded runtime (requires rt-multi-thread feature)
#[cfg(feature = "rt-multi-thread")]
{
let runtime = Builder::new()
.max_blocking_threads(Some(4))
.build()?;
runtime.block_on(async {
println!("Hello from multi-threaded runtime!");
});
runtime.wait()?;
}
Backend-Specific Usage
// Tokio backend (when tokio feature enabled)
#[cfg(all(feature = "tokio", feature = "time", not(feature = "simulator")))]
use switchy_async::{Builder, task, time};
#[cfg(all(feature = "tokio", feature = "time", not(feature = "simulator")))]
{
let runtime = Builder::new().build()?;
// Spawn tasks
runtime.block_on(async {
let handle = task::spawn(async {
time::sleep(time::Duration::from_millis(100)).await;
"Task completed"
});
let result = handle.await.expect("task should complete");
println!("{}", result);
});
runtime.wait()?;
}
// Additional modules available with features
#[cfg(feature = "io")]
use switchy_async::io; // Async I/O traits and utilities
#[cfg(feature = "sync")]
use switchy_async::sync; // Synchronization primitives
#[cfg(feature = "util")]
use switchy_async::util; // Additional utilities
Simulation Backend
// Simulation backend (when simulator feature enabled)
#[cfg(feature = "simulator")]
use switchy_async::simulator;
#[cfg(feature = "simulator")]
{
let runtime = Builder::new().build()?;
runtime.block_on(async {
// Deterministic async execution for testing
println!("Simulation runtime");
});
}
Thread Management
use switchy_async::thread_id;
// Get unique thread ID
let id = thread_id();
println!("Current thread ID: {}", id);
Macros and Utilities
// Async macros (requires macros feature)
#[cfg(feature = "macros")]
use switchy_async::{select, join, try_join};
#[cfg(feature = "macros")]
{
// Use select! macro
select! {
result1 = async_operation_1() => {
println!("Operation 1 completed: {:?}", result1);
}
result2 = async_operation_2() => {
println!("Operation 2 completed: {:?}", result2);
}
}
// Use join! macro
let (result1, result2) = join!(
async_operation_1(),
async_operation_2()
);
// Use try_join! macro for Results
let (result1, result2) = try_join!(
fallible_async_operation_1(),
fallible_async_operation_2()
)?;
}
// Yield injection for simulation testing (requires macros feature)
#[cfg(feature = "macros")]
use switchy_async::{inject_yields, inject_yields_mod};
#[cfg(feature = "macros")]
#[inject_yields]
async fn my_async_function() {
// Function body with automatic yield injection for deterministic testing
}
// Runtime entry-point macros
#[cfg(feature = "macros")]
#[switchy_async::main]
async fn main() {
println!("Runs with the selected switchy_async backend");
}
#[cfg(feature = "macros")]
#[switchy_async::test]
async fn my_test() {
assert_eq!(2 + 2, 4);
}
Error Handling
use switchy_async::Error;
// Runtime errors
match runtime.wait() {
Ok(()) => println!("Runtime completed successfully"),
Err(Error::IO(io_err)) => println!("I/O error: {}", io_err),
Err(Error::Join(join_err)) => println!("Join error: {}", join_err),
}
// Task join errors (when using task handles)
use switchy_async::task::JoinError;
let handle = runtime.spawn(async { /* ... */ });
match handle.await {
Ok(result) => println!("Task completed: {:?}", result),
Err(e) => println!("Task failed: {}", e),
}
Feature Flags
Backend Selection
tokio: Enable Tokio async runtimesimulator: Enable simulation runtime for testing
Runtime Features
rt-multi-thread: Multi-threaded runtime supportfs: File system operationsio: Async I/O operationsnet: Networking supportprocess: Process managementsync: Synchronization primitives (includes channels)time: Timing utilitiesutil: Additional utilitiesmacros: Async macros (select!, join!, try_join!, etc.)
Macro Features
macros: Enable async macros and yield injection utilities
Runtime Comparison
Tokio Runtime
- Production: Optimized for production use
- Performance: High-performance async execution
- Ecosystem: Full Tokio ecosystem support
- Threading: Multi-threaded execution
Simulation Runtime
- Testing: Deterministic execution for tests
- Reproducible: Consistent behavior across runs
- Debugging: Easier debugging and tracing
- Controlled: Precise control over execution order
Dependencies
Core dependencies:
- thiserror: Error handling
- pin-project-lite: Pin projection utilities
- scoped-tls: Scoped thread-local storage
- log: Logging facade
Feature-gated dependencies:
- futures: Core Future trait and utilities (enabled with backend features)
- tokio: Tokio async runtime (optional, enabled with
tokiofeature) - tokio-util: Additional Tokio utilities (optional, enabled with
tokioorutilfeatures) - flume: MPSC/MPMC channel implementation (optional, enabled with
syncfeature) - switchy_async_macros: Macro utilities (optional, enabled with
macrosfeature) - switchy_random: Random number generation for simulator (optional, enabled with
simulatorfeature) - switchy_time: Time utilities for simulator (optional, enabled with
simulatorfeature)
Integration
This package is designed for:
- Application Runtime: Main async runtime for applications
- Testing: Deterministic async testing with simulation
- Library Development: Runtime-agnostic async libraries
- Performance: High-performance async applications
- Cross-Platform: Consistent async behavior across platforms
Dependencies
~1.8–5MB
~85K SLoC