throttlecrab_server/
lib.rs

1//! # ThrottleCrab Server
2//!
3//! A high-performance, standalone rate limiting service with multiple protocol support.
4//!
5//! ## Purpose
6//!
7//! ThrottleCrab Server solves the problem of distributed rate limiting by providing
8//! a centralized service that multiple applications can use to enforce rate limits.
9//! Instead of implementing rate limiting logic in every service, you can:
10//!
11//! - **Centralize rate limiting logic** in one place
12//! - **Share rate limit state** across multiple services
13//! - **Enforce consistent policies** across your entire infrastructure
14//! - **Scale independently** from your application services
15//!
16//! ## Use Cases
17//!
18//! - **API Gateway Rate Limiting**: Protect backend services from overload
19//! - **Multi-Service Rate Limiting**: Share rate limits across microservices
20//! - **User Action Throttling**: Prevent abuse across multiple endpoints
21//! - **Resource Protection**: Guard expensive operations with global limits
22//!
23//! ## Installation
24//!
25//! ```bash
26//! cargo install throttlecrab-server
27//! ```
28//!
29//! ## Quick Start
30//!
31//! ```bash
32//! # Show all available options
33//! throttlecrab-server --help
34//!
35//! # Start with http transport on port 8080
36//! throttlecrab-server --http --http-port 8080
37//!
38//! # Enable multiple protocols
39//! throttlecrab-server --http --grpc --native
40//!
41//! # Custom store configuration
42//! throttlecrab-server --http --http-port 8080 --store adaptive --store-capacity 100000 --store-cleanup-interval 60
43//! ```
44//!
45//! ## Configuration
46//!
47//! Configure via CLI arguments or environment variables (CLI takes precedence):
48//!
49//! ```bash
50//! # Via CLI
51//! throttlecrab-server --http --http-port 9090 --store periodic
52//!
53//! # Via environment variables
54//! export THROTTLECRAB_HTTP=true
55//! export THROTTLECRAB_HTTP_PORT=9090
56//! export THROTTLECRAB_STORE=periodic
57//! throttlecrab-server
58//!
59//! # List all available environment variables
60//! throttlecrab-server --list-env-vars
61//! ```
62//!
63//! ### Key Configuration Options
64//!
65//! - **Transports**: Enable with `--http`, `--grpc`, `--native` (at least one required)
66//! - **Ports**: `--http-port 8080`, `--grpc-port 50051`, `--native-port 8072`
67//! - **Store Type**: `--store periodic|probabilistic|adaptive`
68//! - **Store Capacity**: `--store-capacity 100000`
69//! - **Log Level**: `--log-level error|warn|info|debug|trace`
70//!
71//! ## How It Works
72//!
73//! The server uses GCRA (Generic Cell Rate Algorithm) with a token bucket approach:
74//! - Each key gets a bucket with `max_burst` capacity
75//! - Tokens refill at `count_per_period / period` per second
76//! - Requests consume `quantity` tokens (default: 1)
77//! - Denied requests receive `retry_after` and `reset_after` times
78//!
79//! ## Available Protocols
80//!
81//! - **HTTP/JSON**: Easy integration with any programming language (173K req/s)
82//! - **gRPC**: Service mesh and microservices integration (163K req/s)
83//! - **Native Binary Protocol**: Maximum performance with minimal overhead (183K req/s)
84//!
85//! All protocols share the same underlying rate limiter, ensuring consistent
86//! rate limiting across different client types. RPS are provided for comparison
87//! purposes only.
88//!
89//! ## Architecture
90//!
91//! The server uses an actor-based architecture with Tokio for async I/O:
92//!
93//! ```text
94//! ┌─────────────┐   ┌─────────────┐   ┌─────────────┐
95//! │   Native    │   │    HTTP     │   │    gRPC     │
96//! │  Transport  │   │  Transport  │   │  Transport  │
97//! └──────┬──────┘   └──────┬──────┘   └──────┬──────┘
98//!        │                 │                 │
99//!        └─────────────────┴─────────────────┘
100//!                          │
101//!                    ┌─────▼─────┐
102//!                    │   Actor   │
103//!                    │  (Shared  │
104//!                    │   State)  │
105//!                    └─────┬─────┘
106//!                          │
107//!                    ┌─────▼─────┐
108//!                    │RateLimiter│
109//!                    │   Store   │
110//!                    └───────────┘
111//! ```
112//!
113//! ## Performance
114//!
115//! Benchmark results on modern hardware:
116//!
117//! | Protocol | Throughput | P99 Latency | P50 Latency |
118//! |----------|------------|-------------|-------------|
119//! | Native   | 183K req/s | 263 μs      | 170 μs      |
120//! | HTTP     | 173K req/s | 309 μs      | 177 μs      |
121//! | gRPC     | 163K req/s | 370 μs      | 186 μs      |
122//!
123//! ## Usage
124//!
125//! ### Starting the Server
126//!
127//! ```bash
128//! # HTTP protocol only
129//! throttlecrab-server --http --http-port 8080
130//!
131//! # All protocols
132//! throttlecrab-server --native --http --grpc
133//! ```
134//!
135//! ### Client Examples
136//!
137//! #### HTTP Protocol (curl)
138//! ```bash
139//! curl -X POST http://localhost:8080/throttle \
140//!   -H "Content-Type: application/json" \
141//!   -d '{"key": "user:123", "max_burst": 10, "count_per_period": 100, "period": 60}'
142//! ```
143//!
144//! #### gRPC Protocol
145//! Use any gRPC client library with the provided protobuf definitions.
146//!
147//! #### Native Protocol (Rust)
148//! ```ignore
149//! use std::io::{Read, Write};
150//! use std::net::TcpStream;
151//! use std::time::{SystemTime, UNIX_EPOCH};
152//!
153//! // Connect to server
154//! let mut stream = TcpStream::connect("127.0.0.1:8072")?;
155//!
156//! // Prepare request
157//! let key = "user:123";
158//! let timestamp = SystemTime::now()
159//!     .duration_since(UNIX_EPOCH)?
160//!     .as_nanos() as i64;
161//!
162//! // Write request (42 bytes + key length)
163//! let mut request = Vec::new();
164//! request.push(1u8);                           // cmd: 1 for rate_limit
165//! request.push(key.len() as u8);               // key_len
166//! request.extend_from_slice(&10i64.to_le_bytes());   // max_burst
167//! request.extend_from_slice(&100i64.to_le_bytes());  // count_per_period
168//! request.extend_from_slice(&60i64.to_le_bytes());   // period (seconds)
169//! request.extend_from_slice(&1i64.to_le_bytes());    // quantity
170//! request.extend_from_slice(&timestamp.to_le_bytes()); // timestamp
171//! request.extend_from_slice(key.as_bytes());   // key
172//!
173//! stream.write_all(&request)?;
174//! stream.flush()?;
175//!
176//! // Read response (34 bytes)
177//! let mut response = [0u8; 34];
178//! stream.read_exact(&mut response)?;
179//!
180//! let ok = response[0] == 1;
181//! let allowed = response[1] == 1;
182//! let limit = i64::from_le_bytes(response[2..10].try_into()?);
183//! let remaining = i64::from_le_bytes(response[10..18].try_into()?);
184//! let retry_after = i64::from_le_bytes(response[18..26].try_into()?);
185//! let reset_after = i64::from_le_bytes(response[26..34].try_into()?);
186//!
187//! println!("Allowed: {}, Remaining: {}/{}", allowed, remaining, limit);
188//! ```
189
190pub mod actor;
191pub mod config;
192pub mod store;
193pub mod transport;
194pub mod types;
195
196// Re-export grpc types for tests
197pub mod grpc {
198    pub use crate::transport::grpc::throttlecrab_proto::*;
199}