A Rust-based coroutine and flow control system inspired by CsharpFlow, designed for both async/await and threading workloads.
- Async/Await Support: Built on top of Tokio for asynchronous execution
- Threading Support: Crossbeam-based threading utilities for CPU-bound tasks
- Flow Control: Sequences, barriers, triggers, and more for coordinating execution
- Timers and Futures: Time-based and value-based coordination primitives
- Clean API: Fluent, composable API similar to the original CsharpFlow
Base objects that can be active, completed, named, and stepped through time.
Transients that produce values and can be resumed, suspended, and stepped.
- Node: Executes all child generators when stepped
- Group: Contains transients but doesn't step them automatically
- Sequence: Executes generators one after another
- Barrier: Waits for all dependencies to complete
- Future: Represents a value that will be available later
- Timer: Completes after a specified duration
- Channel: Message passing between flow components
Add to your Cargo.toml
:
[dependencies]
rust_flow = { path = "." }
tokio = { version = "1.0", features = ["full"] }
tracing = "0.1"
Basic example:
use rust_flow::*;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
init_tracing();
let runtime = Runtime::new();
let kernel = runtime.kernel();
{
let factory = kernel.read().await.factory().clone();
let root = kernel.read().await.root();
// Create a simple sequence
let sequence = factory.sequence();
let timer1 = factory.timer(Duration::from_secs(1));
let timer2 = factory.timer(Duration::from_secs(2));
{
let mut seq = sequence.write().await;
seq.add_step(timer1 as Arc<RwLock<dyn Transient>>).await;
seq.add_step(timer2 as Arc<RwLock<dyn Transient>>).await;
}
let mut root_guard = root.write().await;
root_guard.add(sequence as Arc<RwLock<dyn Transient>>).await;
}
// Run for 5 seconds with 16ms frame time
runtime.run_for(Duration::from_secs(5), Duration::from_millis(16)).await?;
Ok(())
}
See the examples/
directory for more comprehensive examples:
game_loop.rs
: Shows a typical game loop structure with start/main/end phasesasync_tasks.rs
: Demonstrates async task coordination with futures
Run examples with:
cargo run --example game_loop
cargo run --example async_tasks
RustFlow is built around several core concepts:
- Kernel: The main execution engine that steps through flow components
- Runtime: Provides frame-based execution with configurable timing
- Factory: Creates all flow components with proper lifecycle management
- Flow Components: Various primitives for coordinating execution
RustFlow supports both paradigms:
- Use async/await for I/O-bound tasks and natural async coordination
- Use the threading module for CPU-bound parallel work
- Mix both approaches as needed in the same application
CsharpFlow | RustFlow | Notes |
---|---|---|
IKernel | Kernel | Main execution engine |
IFactory | Factory | Component creation |
IGenerator | Generator trait | Base execution unit |
INode | Node | Executes child components |
ISequence | Sequence | Sequential execution |
IBarrier | Barrier | Wait for dependencies |
IFuture | Future | Async value container |
ITimer | Timer | Time-based completion |
RustFlow includes a comprehensive test suite with multiple testing strategies:
Core functionality tests embedded in source files:
cargo test --lib
Full system tests demonstrating real-world scenarios:
cargo test --test test_integration
Detailed tests for individual flow components:
cargo test --test test_flow_components
cargo test --test test_kernel_runtime
cargo test --test test_threading_async
Automated testing with generated inputs using quickcheck and proptest:
cargo test --test test_property_based
Performance testing and optimization:
cargo bench
cargo test
The test suite covers:
- Unit Tests: Core types, traits, and basic functionality
- Component Tests: All flow components (timers, futures, sequences, barriers, etc.)
- Kernel Tests: Core execution engine functionality
- Runtime Tests: Frame-based execution and lifecycle management
- Threading Tests: Multi-threaded execution and coordination
- Async Tests: Future-based coordination and async/await patterns
- Integration Tests: Complete workflows and complex scenarios
- Property Tests: Invariant checking with generated test cases
- Stress Tests: High-load scenarios and performance validation
- Benchmarks: Performance measurement and regression detection
Build and test:
cargo build
cargo test
cargo clippy
cargo bench
MIT License - see LICENSE file for details.