# async_sync Effortlessly integrate synchronous and asynchronous code in Rust. The `async_sync` crate simplifies the boundaries between sync and async workflows, providing tools for retry mechanisms, backoff strategies, timeouts, diagnostics, and parallel execution of sync tasks. ## Features - **Retry Mechanisms**: With configurable backoff strategies (constant, linear, exponential). - **Timeout Handling**: Include optional cleanup logic on timeout. - **Parallel Execution**: Run multiple sync tasks concurrently. - **Integration**: Seamlessly works with `Tokio` and `Async-std` runtimes. - **Diagnostics**: Log execution times and track performance. --- ## Getting Started Add `async_sync` to your `Cargo.toml`: ```toml [dependencies] async_sync = "0.1.0" tokio = { version = "1", features = ["full"] } ``` ## Examples ### Retry with Backoff Strategy Handle transient failures in sync tasks with retries and exponential backoff. ```rust use async_sync::{sync_to_async_with_retries, Backoff}; use std::sync::{Arc, Mutex}; use std::time::Duration; fn flaky_function(counter: Arc>) -> Result { let mut count = counter.lock().unwrap(); *count += 1; if *count < 3 { Err("Failure") } else { Ok("Success") } } #[tokio::main] async fn main() { let counter = Arc::new(Mutex::new(0)); let result = sync_to_async_with_retries( || flaky_function(Arc::clone(&counter)), 5, // Max retries Duration::from_millis(100), // Initial delay Backoff::Exponential, // Backoff strategy ) .await; match result { Ok(value) => println!("Task succeeded: {}", value), Err(err) => eprintln!("Task failed: {:?}", err), } } ``` ## Examples ### Retry with Backoff Strategy Handle transient failures in sync tasks with retries and exponential backoff. ```rust use async_sync::{sync_to_async_with_retries, Backoff}; use std::sync::{Arc, Mutex}; use std::time::Duration; fn flaky_function(counter: Arc>) -> Result { let mut count = counter.lock().unwrap(); *count += 1; if *count < 3 { Err("Failure") } else { Ok("Success") } } #[tokio::main] async fn main() { let counter = Arc::new(Mutex::new(0)); let result = sync_to_async_with_retries( || flaky_function(Arc::clone(&counter)), 5, // Max retries Duration::from_millis(100), // Initial delay Backoff::Exponential, // Backoff strategy ) .await; match result { Ok(value) => println!("Task succeeded: {}", value), Err(err) => eprintln!("Task failed: {:?}", err), } } ``` ### Parallel Execution of Sync Tasks Execute multiple synchronous tasks in parallel and collect their results. ```rust use async_sync::parallel_sync_to_async; fn heavy_computation(x: i32) -> i32 { std::thread::sleep(std::time::Duration::from_millis(200)); x * x } #[tokio::main] async fn main() { let tasks: Vec<_> = (1..=5).map(|x| move || heavy_computation(x)).collect(); let results = parallel_sync_to_async(tasks).await; for (i, result) in results.into_iter().enumerate() { println!("Task {} result: {:?}", i + 1, result.unwrap()); } } ``` ### Sync-Async Integration with Runtimes Run sync functions using the `Tokio` or `Async-std` runtime. ```rust use async_sync::{sync_to_async_with_runtime, Runtime}; fn heavy_computation(x: i32) -> i32 { std::thread::sleep(std::time::Duration::from_millis(200)); x * x } fn main() { let result = sync_to_async_with_runtime(Runtime::Tokio, || heavy_computation(4)); println!("Result: {:?}", result.unwrap()); } ``` --- ## Contact If you have any questions, feedback, or just want to connect, feel free to reach out! - **Matthew Novak** Email: [matt@packetandpine.com](mailto:matt@packetandpine.com) Website: [https://packetandpine.com](https://packetandpine.com) Twitter: [https://x.com/PacketAndPine](https://x.com/PacketAndPine) YouTube: [https://www.youtube.com/@PacketAndPine](https://www.youtube.com/@PacketAndPine)