bach 0.1.1

Discrete-event simulation environment for async workflows
Documentation
# Bach

**Bach** is a Rust-based framework for simulating and testing complex async/await-based systems in a non-real-time environment. It's capable of modeling network protocols, queueing systems, and concurrent task interactions with testing and visualization tools.

## Key Features
- **Discrete Event Simulation**: Schedules events in simulated time for deterministic testing.
- **Async/Await Integration**: Supports any async that doesn't require a specific runtime, like `tokio` or `async-std`.
- **Composable Queues**: Build flexible queues with latency, packet loss, mutexes, and sojourn tracking.
- **Network Simulation**: Simulates UDP sockets with configurable latency, loss, reordering, and duplication; TCP support planned for the near future.
- **[Partial Order Reduction]https://en.wikipedia.org/wiki/Partial_order_reduction**: Optimizes task interleaving testing using a [disjoint set]https://en.wikipedia.org/wiki/Disjoint-set_data_structure, reducing the search space for conflicting resource accesses.
- **PCAP Exporting**: Captures simulated network traffic as PCAP files for analysis with Wireshark.
- **[Bolero]https://github.com/camshaft/bolero Integration**: Enables exhaustive and non-exhaustive (fuzzing-based) interleaving testing using engines like [libFuzzer]https://llvm.org/docs/LibFuzzer.html, with corpus replay and basic RNG input generation for `cargo test`.
- **Monitoring**: Tracks packet sends, socket reads/writes, and supports fault injection.
- **WASM Support**: Can compile to WebAssembly and run in the browser for interactive simulations

## Example: Simulating a Networked Ping-Pong

This example simulates two clients sending "ping" to a server over UDP, which responds with "pong".

```rust
use bach::{ext::*, net::UdpSocket};

#[test]
fn ping_pong() {
    bach::sim(|| {
        for i in 0..2 {
            async move {
                let socket = UdpSocket::bind("0.0.0.0:0").await.unwrap();
                socket.send_to(b"ping", "server:8080").await.unwrap();
                let mut data = [0; 4];
                let (len, _) = socket.recv_from(&mut data).await.unwrap();
                assert_eq!(&data[..len], b"pong");
            }
            .group(format!("client_{i}"))
            .primary()
            .spawn();
        }

        async {
            let socket = UdpSocket::bind("server:8080").await.unwrap();
            loop {
                let mut data = [0; 4];
                let (len, addr) = socket.recv_from(&mut data).await.unwrap();
                assert_eq!(&data[..len], b"ping");
                socket.send_to(b"pong", addr).await.unwrap();
            }
        }
        .group("server")
        .spawn();
    });
}
```

This test can be executed with the following command, while also exporting pcaps showing the interaction between the tasks:

```bash
$ BACH_PCAP_DIR=target/bach/pcaps cargo test
```

## Installation

Add to `Cargo.toml`:
```toml
[dependencies]
bach = "0.1"
```

## Related Projects

- **[aws/s2n-quic]https://github.com/aws/s2n-quic**: A QUIC protocol implementation. Employs Bach’s UDP-based network simulation to test high-level protocol behaviors, such as correctness, using PCAP exporting, fault injection, and [monte-carlo simulations]https://dnglbrstg7yg.cloudfront.net/8f7696e6d3163286a915ec29a6d0bd709c946ee8/sim/index.html#network_jitter/duration.json.
- **[camshaft/kew]https://github.com/camshaft/kew**: A book about queueing theory. Utilizes Bach to simulate and visualize queue behaviors (e.g., FIFO, priority queues) in a browser via WebAssembly.
- **[camshaft/euphony-rs]https://github.com/camshaft/euphony-rs**: A music composition environment. Uses Bach to schedule musical events (e.g., notes, rhythms) in non-real-time simulations for algorithmic composition.

Explore the [Bach repository](https://github.com/camshaft/bach) for more details or to contribute!