Orbit-RS Quick Start Guide

One Server, All Protocols, Persistent Storage - Get a production-ready multi-protocol database server with RocksDB persistence running in 30 seconds.

πŸš€ What You’ll Get

Single orbit-server command gives you:

πŸ”‘ Key Innovation: Same data accessible through any protocol with instant consistency and full persistence!

Prerequisites

Before you begin, ensure you have the following installed:

Installing Protocol Buffers

macOS

brew install protobuf

Ubuntu/Debian

sudo apt update
sudo apt install protobuf-compiler

Windows

Download from Protocol Buffers releases or use:

choco install protoc

⚑ 30-Second Quick Start

1. Clone and Build

git clone https://github.com/TuringWorks/orbit-rs.git
cd orbit-rs
cargo build --release

2. Start the Multi-Protocol Server

# Start server with all protocols enabled
./target/release/orbit-server --dev-mode

# 🎯 Server starting with all protocols and persistent storage:
# gRPC:      localhost:50051 (Orbit clients)
# PostgreSQL: localhost:5432  (psql, PostgreSQL clients) - PERSISTED
# Redis:     localhost:6379  (redis-cli, Redis clients) - PERSISTED
# MySQL:     localhost:3306  (mysql clients) - PERSISTED
# CQL:       localhost:9042  (cqlsh, Cassandra clients) - PERSISTED
# REST API:  localhost:8080  (HTTP/JSON)
# Data:      ./data/rocksdb  (LSM-tree files)

3. Connect with Standard Clients

PostgreSQL - Use any PostgreSQL client:

psql -h localhost -p 5432 -U orbit -d actors

Redis - Use redis-cli or any Redis client:

redis-cli -h localhost -p 6379

MySQL - Use mysql client:

mysql -h localhost -P 3306 -u orbit -p

gRPC - Use OrbitClient or grpcurl:

# List gRPC services
grpcurl -plaintext localhost:50051 list

4. Verify Multi-Protocol Access

# Test all protocols are working
psql -h localhost -p 5432 -U orbit -d actors -c "SELECT 'PostgreSQL Connected!';"
redis-cli -h localhost -p 6379 ping
curl http://localhost:8080/health
grpcurl -plaintext localhost:50051 orbit.HealthService/Check

πŸ”„ Multi-Protocol Data Demo

The same data is accessible through all protocols - here’s how:

Cross-Protocol Data Consistency Demo

The key innovation: Same data, different protocols!

# Terminal 1: Write data via Redis
redis-cli -h localhost -p 6379
127.0.0.1:6379> SET greeting "Hello from Redis!"
OK
127.0.0.1:6379> HSET user:alice name "Alice" email "alice@orbit.com" role "admin"
(integer) 3

# Terminal 2: Create table and insert via PostgreSQL
psql -h localhost -p 5432 -U orbit -d actors
actors=# CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT, email TEXT, role TEXT);
CREATE TABLE
actors=# INSERT INTO users (name, email, role) VALUES ('Bob', 'bob@orbit.com', 'user');
INSERT 0 1

# Terminal 3: Query via REST API
curl "http://localhost:8080/api/users"

✨ Same underlying data store, multiple protocol interfaces!

Time Series Operations

# Redis TimeSeries commands
redis-cli -h localhost -p 6379

# Create time series with retention and labels
127.0.0.1:6379> TS.CREATE temperature:sensor1 RETENTION 86400000 LABELS sensor_id 1 location warehouse
OK

# Add samples (auto-timestamp)
127.0.0.1:6379> TS.ADD temperature:sensor1 * 23.5
(integer) 1701234567890

# Query range with aggregation
127.0.0.1:6379> TS.RANGE temperature:sensor1 - + AGGREGATION avg 3600000
1) 1) (integer) 1701234000000
   2) "23.5"

# Multi-key query with filters
127.0.0.1:6379> TS.MRANGE - + FILTER location=warehouse
1) 1) "temperature:sensor1"
   2) 1) 1) "sensor_id"
         2) "1"
      2) 1) "location"
         2) "warehouse"
   3) 1) 1) (integer) 1701234567890
         2) "23.5"

Vector Operations Across Protocols

# PostgreSQL with pgvector
psql -h localhost -p 5432 -U orbit -d actors
actors=# CREATE EXTENSION IF NOT EXISTS vector;
actors=# CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    content TEXT,
    embedding VECTOR(3)  -- Using 3D vectors for demo
);
actors=# INSERT INTO documents (content, embedding) VALUES 
    ('Machine learning', '[0.1, 0.2, 0.3]'),
    ('Deep learning', '[0.15, 0.25, 0.35]'),
    ('Data science', '[0.2, 0.3, 0.4]');

# Vector similarity search via SQL
actors=# SELECT content, embedding <-> '[0.1, 0.2, 0.3]' AS distance 
         FROM documents 
         ORDER BY embedding <-> '[0.1, 0.2, 0.3]' 
         LIMIT 2;
# Same vector operations via Redis
redis-cli -h localhost -p 6379

# Add vectors with metadata
127.0.0.1:6379> VECTOR.ADD doc-embeddings doc1 "0.1,0.2,0.3" content "Machine learning"
127.0.0.1:6379> VECTOR.ADD doc-embeddings doc2 "0.15,0.25,0.35" content "Deep learning"
127.0.0.1:6379> VECTOR.ADD doc-embeddings doc3 "0.2,0.3,0.4" content "Data science"

# Vector similarity search
127.0.0.1:6379> VECTOR.SEARCH doc-embeddings "0.1,0.2,0.3" 2 METRIC COSINE
1) 1) "doc1"
   2) "1.000000"
2) 1) "doc2"
   2) "0.998"

REST API Access

# Query data via HTTP REST API
curl "http://localhost:8080/api/users"
curl "http://localhost:8080/api/users/1"

# Vector search via REST
curl -X POST "http://localhost:8080/api/vectors/search" \
  -H "Content-Type: application/json" \
  -d '{
    "collection": "doc-embeddings",
    "vector": [0.1, 0.2, 0.3],
    "limit": 5,
    "metric": "cosine"
  }'

# Health and status endpoints
curl http://localhost:8080/health
curl http://localhost:8080/metrics

πŸ“š Basic Usage

Simple Actor Example

Here’s a minimal example to get you started with Orbit-RS:

use orbit_client::{OrbitClient, OrbitClientConfig};
use orbit_shared::{ActorWithStringKey, Key};
use async_trait::async_trait;

// Define an actor trait
#[async_trait]
trait GreeterActor: ActorWithStringKey {
    async fn greet(&self, name: String) -> Result<String, orbit_shared::OrbitError>;
}

// Implement the actor
struct GreeterActorImpl;

#[async_trait]
impl GreeterActor for GreeterActorImpl {
    async fn greet(&self, name: String) -> Result<String, orbit_shared::OrbitError> {
        Ok(format!("Hello, {}!", name))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a client with configuration
    let config = OrbitClientConfig {
        namespace: "demo".to_string(),
        server_urls: vec!["http://localhost:50051".to_string()],
        ..Default::default()
    };
    
    let client = OrbitClient::new(config).await?;
    
    // Get an actor reference
    let greeter = client.actor_reference::<dyn GreeterActor>(
        Key::StringKey { key: "my-greeter".to_string() }
    ).await?;
    
    // Invoke the actor
    let greeting = greeter.greet("World".to_string()).await?;
    println!("{}", greeting); // "Hello, World!"
    
    Ok(())
}

Distributed Transactions Example

For more advanced usage with distributed transactions:

use orbit_shared::{
    transactions::*,
    transport::*,
    AddressableReference, Key, NodeId,
};
use std::{sync::Arc, time::Duration};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create transaction coordinator
    let node_id = NodeId::new("coordinator".to_string(), "cluster".to_string());
    let config = TransactionConfig::default();
    let transport = Arc::new(GrpcTransactionMessageSender::new(/* ... */));
    
    let coordinator = TransactionCoordinator::new(node_id, config, transport);
    
    // Begin distributed transaction
    let tx_id = coordinator.begin_transaction(Some(Duration::from_secs(30))).await?;
    
    // Add banking operations
    let debit_operation = TransactionOperation::new(
        AddressableReference {
            addressable_type: "BankAccount".to_string(),
            key: Key::StringKey { key: "alice".to_string() },
        },
        "debit".to_string(),
        serde_json::json!({"amount": 100}),
    ).with_compensation(serde_json::json!({"amount": 100, "action": "credit"}));
    
    let credit_operation = TransactionOperation::new(
        AddressableReference {
            addressable_type: "BankAccount".to_string(),
            key: Key::StringKey { key: "bob".to_string() },
        },
        "credit".to_string(),
        serde_json::json!({"amount": 100}),
    ).with_compensation(serde_json::json!({"amount": 100, "action": "debit"}));
    
    coordinator.add_operation(&tx_id, debit_operation).await?;
    coordinator.add_operation(&tx_id, credit_operation).await?;
    
    // Execute 2-phase commit
    coordinator.commit_transaction(&tx_id).await?;
    
    println!("βœ… Transaction {} committed successfully!", tx_id);
    Ok(())
}

βš™οΈ Configuration

Development vs Production Modes

Development Mode (--dev-mode):

# Development - all protocols active
orbit-server --dev-mode

Production Mode:

# Production with configuration file
orbit-server --config /etc/orbit/production.toml

Production Configuration

Create /etc/orbit/production.toml:

[server]
bind_address = "0.0.0.0"
environment = "Production"
node_id = "orbit-prod-01"

# Enable only needed protocols
[protocols.postgresql]
enabled = true
port = 5432
max_connections = 5000

[protocols.redis]  
enabled = true
port = 6379
max_connections = 5000

[protocols.mysql]
enabled = true
port = 3306
max_connections = 5000

[protocols.cql]
enabled = true
port = 9042
max_connections = 5000

[protocols.rest]
enabled = true
port = 8080

[protocols.grpc]
enabled = true
port = 50051

# Vector operations
[protocols.postgresql.vector_ops]
default_metric = "cosine"
max_dimensions = 1536
batch_size = 1000
enable_simd = true

# Storage configuration
[storage]
backend = "rocksdb"
data_dir = "./data"

[storage.rocksdb]
max_open_files = 10000
write_buffer_size = 67108864  # 64MB
max_write_buffer_number = 3

# Production security
[security.authentication]
enabled = true
methods = ["JWT"]

[security.authentication.jwt]
secret_key = "${JWT_SECRET}"  # From environment
expiration_secs = 3600

# Performance tuning
[performance.memory]
max_memory_mb = 16384  # 16GB

[performance.cpu]
worker_threads = 32
enable_simd = true

# Production logging
[logging]
level = "warn"
format = "json"

[[logging.outputs]]
output_type = "file"
file_path = "/var/log/orbit/orbit-server.log"

# Monitoring
[monitoring.metrics]
enabled = true
port = 9090

[monitoring.health_checks]
enabled = true
port = 8081

Command Line Options

# Enable specific protocols
orbit-server \
  --enable-postgresql \
  --enable-redis \
  --enable-mysql \
  --postgres-port 5432 \
  --redis-port 6379 \
  --mysql-port 3306

# With clustering
orbit-server \
  --config production.toml \
  --seed-nodes node1:7946,node2:7946

πŸ› οΈ Development Setup

IDE Setup

VS Code

Recommended extensions:

IntelliJ IDEA

Development Commands

# Fast compile check
cargo check

# Lint with Clippy
cargo clippy --workspace -- -D warnings

# Format code
cargo fmt --all

# Security audit
cargo audit

# Run benchmarks
cargo bench

Testing

# Run unit tests
cargo test --workspace --lib

# Run integration tests  
cargo test --workspace --test '*'

# Run specific test
cargo test -p orbit-server time_series::

# Run with output
cargo test -- --nocapture

# Run ignored (slow) tests
cargo test -- --ignored

πŸ”§ Troubleshooting

Common Issues

Protocol Buffers Not Found

error: Could not find `protoc` installation

Solution: Install Protocol Buffers compiler as described in prerequisites.

Rust Version Too Old

error: package requires Rust 1.70 or newer

Solution: Update Rust using rustup update

Port Already in Use

error: Address already in use (os error 48)

Solution: Use a different port or stop the conflicting service.

# Find process using port 6379
lsof -i :6379

# Kill the process
kill -9 <PID>

Getting Help

🎯 Next Steps

Now that you have Orbit-RS multi-protocol server running, explore these guides:

Core Documentation

Protocol-Specific Guides

Advanced Features

Development & Operations

Migration Guides


Orbit-RS: One Server, All Protocols πŸš€