/rust-redis-ae

Redis AE Event Loop in Rust

Primary LanguageCOtherNOASSERTION

RAE - Redis AE Event Loop in Rust

A memory-safe, high-performance Rust port of Redis's Asynchronous Event (AE) loop system.

Overview

RAE (Rust Asynchronous Events) is a faithful port of Redis's battle-tested event loop implementation, bringing the same performance and reliability to Rust while leveraging memory safety guarantees and zero-cost abstractions.

The Redis AE event loop is the heart of Redis's high-performance networking, handling millions of concurrent connections with minimal overhead. This Rust implementation maintains API compatibility while eliminating memory safety issues inherent in C.

Features

  • 🚀 High Performance - Zero-cost abstractions with performance matching original C implementation
  • 🛡️ Memory Safe - Leverages Rust's ownership system to eliminate memory corruption and data races
  • 🔄 Cross Platform - Support for Linux (epoll), BSD/macOS (kqueue), and universal (select) backends
  • Asynchronous - Non-blocking I/O with efficient event dispatching
  • 🔧 API Compatible - Drop-in replacement for Redis AE with familiar interface
  • 📊 Production Ready - Based on Redis's proven event loop architecture

Supported Platforms

Platform Backend Status
Linux epoll 🚧 Planned
macOS/BSD kqueue 🚧 Planned
Universal select 🚧 Planned
Solaris event ports 🚧 Planned

Quick Start

use rae::{EventLoop, FileEvent, EventMask};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create event loop
    let mut event_loop = EventLoop::new(1024)?;

    // Register file events
    event_loop.create_file_event(
        fd,
        EventMask::READABLE,
        |event_loop, fd, client_data, mask| {
            // Handle read event
            println!("Data ready to read on fd {}", fd);
        },
        None,
    )?;

    // Register time events
    event_loop.create_time_event(
        1000, // milliseconds
        |event_loop, id, client_data| {
            println!("Timer event fired!");
            0 // Don't reschedule
        },
        None,
        None,
    )?;

    // Run event loop
    event_loop.main();

    Ok(())
}

Installation

Add to your Cargo.toml:

[dependencies]
rae = "0.1.0"

Or install via cargo:

cargo add rae

Architecture

RAE follows Redis's proven event loop architecture:

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   File Events   │    │   Time Events    │    │ Platform Layer  │
│                 │    │                  │    │                 │
│ • Read/Write    │    │ • Timers         │    │ • epoll (Linux) │
│ • Error         │────┼─ • Scheduling    │────┼─ • kqueue (BSD) │
│ • Callbacks     │    │ • Callbacks      │    │ • select (Unix) │
└─────────────────┘    └──────────────────┘    └─────────────────┘
           │                       │                       │
           └───────────────────────┼───────────────────────┘
                                   │
                          ┌────────▼────────┐
                          │   Event Loop    │
                          │                 │
                          │ • Processing    │
                          │ • Dispatching   │
                          │ • Lifecycle     │
                          └─────────────────┘

Key Components

  • EventLoop: Central coordinator managing all events and dispatching
  • FileEvent: Handles I/O events on file descriptors (sockets, pipes, etc.)
  • TimeEvent: Manages timer-based events and scheduling
  • Platform Backends: OS-specific implementations (epoll, kqueue, select)

Performance

RAE is designed for high performance with:

  • Minimal Allocations: Reuses memory where possible during event processing
  • Efficient Dispatching: O(1) event dispatching for most operations
  • Platform Optimization: Uses the most efficient event notification for each OS
  • Zero Copy: Avoids unnecessary data copying in hot paths

Development Status

🚧 Pre-Alpha - Currently in initial development

Roadmap

  • Phase 1: Core event loop structures and API
  • Phase 2: Platform backend implementations
  • Phase 3: Redis test suite port and validation
  • Phase 4: Performance optimization and benchmarking
  • Phase 5: Production hardening and documentation

See AGENTS.md for detailed implementation plan.

Examples

TCP Server

use rae::{EventLoop, EventMask};
use std::net::TcpListener;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080")?;
    listener.set_nonblocking(true)?;

    let mut event_loop = EventLoop::new(1024)?;

    // Accept connections
    event_loop.create_file_event(
        listener.as_raw_fd(),
        EventMask::READABLE,
        |el, fd, _, _| {
            // Accept and register new client
            // ...
        },
        None,
    )?;

    event_loop.main();
    Ok(())
}

Timer Events

use rae::EventLoop;
use std::time::Instant;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut event_loop = EventLoop::new(64)?;
    let start = Instant::now();

    // Recurring timer every second
    event_loop.create_time_event(
        1000,
        move |el, id, _| {
            println!("Tick: {}s elapsed", start.elapsed().as_secs());
            1000 // Reschedule in 1000ms
        },
        None,
        None,
    )?;

    event_loop.main();
    Ok(())
}

Contributing

Contributions are welcome! Please see our contribution guidelines.

Building

git clone https://github.com/pnodet/rae.git
cd rae
cargo build

Testing

cargo test
cargo test --features integration-tests

Benchmarking

cargo bench

License

Licensed under either of:

at your option.

Inspiration

This project is inspired by and based on the Redis event loop implementation. Redis is licensed under the BSD 3-Clause License.

Related Projects

  • tokio - Asynchronous runtime for Rust
  • mio - Metal I/O library for Rust
  • async-std - Async standard library