Skip to content

A high-performance, lock-free disruptor engine written in Rust, implementing the LMAX Disruptor pattern with modern Rust optimizations and disruptor-rs inspired features.

License

Notifications You must be signed in to change notification settings

nebulatrade/badbatch

 
 

Repository files navigation

BadBatch Logo

BadBatch Disruptor Engine

License: AGPL v3 Tests

A high-performance, lock-free disruptor engine written in Rust, implementing the LMAX Disruptor pattern with modern Rust optimizations and disruptor-rs inspired features.

🚀 Features

🔥 LMAX Disruptor Core Engine

  • Lock-free ring buffer with power-of-2 sizing for maximum performance
  • Multiple wait strategies: Blocking, BusySpin, Yielding, Sleeping
  • Event processors with batch processing capabilities
  • Single and multi-producer support with bitmap optimization
  • Comprehensive exception handling with custom error types
  • Sequence barriers and dependency management
  • Event factories, handlers, and translators for flexible event processing
  • Full compatibility with original LMAX Disruptor patterns

⚡ Modern Rust Optimizations (inspired by disruptor-rs)

  • Simplified Producer API: Closure-based publishing with producer.publish(|event| { ... })
  • Batch Publishing: Efficient BatchIterMut for zero-copy batch operations
  • Builder Pattern: Fluent API with build_single_producer(size, factory, wait_strategy)
  • Thread Management: CPU affinity support with ThreadBuilder::new().pin_at_core(1)
  • Elegant Consumer: Automatic lifecycle management with ElegantConsumer::new()
  • Simple Wait Strategies: Streamlined strategies for easier usage

📊 Performance & Safety

  • Zero-cost abstractions with Rust's type system
  • Memory safety without garbage collection
  • Thread safety guaranteed at compile time
  • Lock-free data structures for maximum throughput
  • NUMA-aware design considerations

🏗️ Architecture

BadBatch is a focused, high-performance disruptor library with a clean, modular architecture:

┌─────────────────────────────────────────────────────────────┐
│                    BadBatch Disruptor Library               │
├─────────────────────────────────────────────────────────────┤
│  ⚡ Core Disruptor Engine                                   │
│  ├─ Ring Buffer (Lock-free, Power-of-2 Sizing)             │
│  ├─ Event Processors (Batch Processing)                    │
│  ├─ Wait Strategies (Blocking, BusySpin, Yielding, Sleep)  │
│  ├─ Producer Types (Single/Multi with Bitmap Optimization) │
│  ├─ Sequence Management (Atomic Coordination)              │
│  ├─ Event Factories, Handlers & Translators               │
│  └─ Exception Handling (Custom Error Types)                │
├─────────────────────────────────────────────────────────────┤
│  🚀 Modern Rust Optimizations                              │
│  ├─ Builder Pattern (Fluent API)                           │
│  ├─ Closure-based Publishing                               │
│  ├─ Batch Operations (Zero-copy)                           │
│  ├─ Thread Management (CPU Affinity)                       │
│  ├─ Elegant Consumer (Lifecycle Management)                │
│  └─ Simple Wait Strategies                                  │
├─────────────────────────────────────────────────────────────┤
│  🔧 Performance Features                                    │
│  ├─ Cache Line Padding (False Sharing Prevention)          │
│  ├─ Memory Layout Optimization                             │
│  ├─ Bit Manipulation (Fast Modulo)                         │
│  ├─ NUMA-aware Design                                       │
│  └─ Zero-allocation Runtime                                 │
└─────────────────────────────────────────────────────────────┘

🚀 Quick Start

Installation

From Source

git clone https://github.com/deadjoe/badbatch.git
cd badbatch
cargo build --release

Basic Usage

BadBatch is a library for building high-performance event processing systems. Here's how to use it in your Rust projects:

📖 Programming API

Traditional LMAX Disruptor API

use badbatch::disruptor::{
    Disruptor, ProducerType, BlockingWaitStrategy, DefaultEventFactory,
    EventHandler, EventTranslator, Result,
};

#[derive(Debug, Default)]
struct MyEvent {
    value: i64,
    message: String,
}

// Event handler implementation
struct MyEventHandler;

impl EventHandler<MyEvent> for MyEventHandler {
    fn on_event(&mut self, event: &mut MyEvent, sequence: i64, end_of_batch: bool) -> Result<()> {
        println!("Processing event {} with value {} (end_of_batch: {})",
                 sequence, event.value, end_of_batch);
        Ok(())
    }
}

// Create and configure the Disruptor
let factory = DefaultEventFactory::<MyEvent>::new();
let mut disruptor = Disruptor::new(
    factory,
    1024, // Buffer size (must be power of 2)
    ProducerType::Single,
    Box::new(BlockingWaitStrategy::new()),
)?
.handle_events_with(MyEventHandler)
.build();

// Start the Disruptor
disruptor.start()?;

// Publish events using EventTranslator
struct MyEventTranslator {
    value: i64,
    message: String,
}

impl EventTranslator<MyEvent> for MyEventTranslator {
    fn translate_to(&self, event: &mut MyEvent, _sequence: i64) {
        event.value = self.value;
        event.message = self.message.clone();
    }
}

let translator = MyEventTranslator {
    value: 42,
    message: "Hello, World!".to_string(),
};
disruptor.publish_event(translator)?;

// Shutdown when done
disruptor.shutdown()?;

Modern disruptor-rs Inspired API

use badbatch::disruptor::{
    build_single_producer, Producer, ElegantConsumer, RingBuffer,
    simple_wait_strategy::BusySpin, event_factory::ClosureEventFactory,
};
use std::sync::Arc;

#[derive(Debug, Default)]
struct MyEvent {
    value: i64,
}

// Simple producer with closure-based publishing
let mut producer = build_single_producer(1024, || MyEvent::default(), BusySpin)
    .handle_events_with(|event, sequence, end_of_batch| {
        println!("Processing event {} with value {} (batch_end: {})",
                 sequence, event.value, end_of_batch);
    })
    .build();

// Publish events with closures
producer.publish(|event| {
    event.value = 42;
});

// Batch publishing
producer.batch_publish(5, |batch| {
    for (i, event) in batch.enumerate() {
        event.value = i as i64;
    }
});

// Elegant consumer with CPU affinity
let factory = ClosureEventFactory::new(|| MyEvent::default());
let ring_buffer = Arc::new(RingBuffer::new(1024, factory)?);

let consumer = ElegantConsumer::with_affinity(
    ring_buffer,
    |event, sequence, end_of_batch| {
        println!("Processing: {} at {}", event.value, sequence);
    },
    BusySpin,
    1, // Pin to CPU core 1
)?;

// Graceful shutdown
consumer.shutdown()?;

🔧 Development

Prerequisites

  • Rust 1.70 or later
  • Git

Building

git clone https://github.com/deadjoe/badbatch.git
cd badbatch
cargo build

Testing

# Run all tests
cargo test

# Run comprehensive test suite with quality checks
bash scripts/test-all.sh

# Run specific test categories
cargo test --lib                    # Unit tests
cargo test --test '*'               # Integration tests
cargo test --doc                    # Documentation tests

# Run benchmarks
cargo bench

Code Quality

# Comprehensive quality checks (recommended)
bash scripts/test-all.sh

# Individual quality checks
cargo fmt                           # Format code
cargo clippy --all-targets --all-features -- -D warnings  # Lint code
cargo audit                         # Security audit
cargo deny check                    # Dependency management

# Documentation
cargo doc --no-deps --open          # Generate and open docs
cargo test --doc                    # Test documentation examples

# Coverage analysis (requires cargo-llvm-cov)
cargo llvm-cov --lib --html         # Generate HTML coverage report

📈 Performance

BadBatch is designed for high-performance event processing with the following characteristics:

Core Performance Features

  • Lock-free architecture: Zero-cost abstractions with no locks in hot paths
  • Memory efficiency: Pre-allocated ring buffer with zero runtime allocation
  • CPU optimization: Cache-friendly data structures with proper padding
  • Rust advantages: Memory safety without runtime overhead
  • Mechanical sympathy: NUMA-aware design and CPU affinity support

Optimization Techniques

  • Cache Line Padding: Uses crossbeam_utils::CachePadded to prevent false sharing
  • Bitmap Optimization: O(1) availability checking for large buffers (inspired by disruptor-rs)
  • Batch Processing: Automatic batching reduces coordination overhead
  • Bit Manipulation: Fast modulo operations using bit masks for power-of-2 buffer sizes
  • Memory Layout: Optimal data structures (Box<[UnsafeCell<T>]>) for better cache locality

🤝 Contributing

We welcome contributions! Please follow these steps:

Development Process

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Run the test suite
  6. Submit a pull request

Code of Conduct

This project adheres to the Rust Code of Conduct.

📄 License

This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).

See the LICENSE file for details.

🙏 Acknowledgments

📞 Support


Made with ❤️ in Rust

About

A high-performance, lock-free disruptor engine written in Rust, implementing the LMAX Disruptor pattern with modern Rust optimizations and disruptor-rs inspired features.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 90.3%
  • TLA 6.9%
  • Shell 2.8%