chopin-core
High-fidelity engineering for the modern virtuoso.
chopin-core is the zero-overhead HTTP engine powering the Chopin framework. It outperforms async runtimes like Tokio/Hyper by 5–6× on pipelined workloads using a synchronous, shared-nothing architecture.
Benchmark (Mac, 10 cores, 512 connections, 16-deep pipeline)
| Framework | Pipelined req/s |
|---|---|
| chopin-core | ~21M |
| hyper (Tokio) | ~440K |
No
async, noArc, noMutex. Each worker thread is a fully self-contained event loop.
Architecture
┌──────────────────────────────────────────────────────────────┐
│ chopin-core │
│ │
│ Server::bind("0.0.0.0:8080") │
│ │ │
│ ├── Worker 0 (SO_REUSEPORT fd) ──► epoll/kqueue loop │
│ ├── Worker 1 (SO_REUSEPORT fd) ──► epoll/kqueue loop │
│ ├── Worker 2 (SO_REUSEPORT fd) ──► epoll/kqueue loop │
│ └── Worker N (SO_REUSEPORT fd) ──► epoll/kqueue loop │
│ │
│ Per-Worker Hot Path: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ epoll_wait() │ │
│ │ └─► Accept / Read / Parse (zero-copy parser) │ │
│ │ └─► Router O(1) fast-table → Handler fn() │ │
│ │ └─► Serialize into write_buf │ │
│ │ └─► Batch write (1 syscall │ │
│ │ for N pipelined requests) │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Design Principles
| Principle | Implementation |
|---|---|
| No async runtime | Every worker is a plain OS thread with a loop { epoll_wait() } |
| Shared-nothing | Each worker owns: event loop, accept socket, connection slab, router clone |
| Zero allocation hot path | Stack-allocated parse buffers, pre-baked header strings, mimalloc allocator |
| Pipeline batching | Small responses copy into write_buf; a single write() drains N pipelined requests |
| O(1) routing | Static routes resolved from a HashMap pre-built at startup; trie only for dynamic paths |
| SO_REUSEPORT | Each worker binds its own listen socket — kernel distributes connections without a shared queue |
Quick Start
Macro Style (recommended)
use ;
use KJson;
Manual Router Style
use ;
Routing
HTTP Methods
Path Parameters
Wildcard Segments
Sub-Routers (nest / merge)
let mut api = new;
api.get;
api.post;
let mut root = new;
root = root.nest; // mounts at /api/v1/status, /api/v1/login
Request Handling
Accessing Request Data
JSON Extraction
use Json;
use KJson;
Query String Extraction
use Query;
use HashMap;
Responses
// Plain text (static — zero allocation)
text_static
// Plain text (owned)
text
// JSON (serialized via KJson)
json
// JSON from pre-serialized bytes
json_bytes
// HTML
html
// Redirect
redirect
// 404 / 400 / 500
not_found
bad_request
server_error
// Custom status + headers
text
.with_status
.with_header
// File download (sendfile — zero-copy)
file
// Chunked streaming
stream
Middleware
Middleware wraps handlers and can read/modify the request/response.
use ;
// Global middleware (applies to all routes)
let mut router = new;
router.layer;
router.layer;
// Path-scoped middleware
router.layer_path;
WebSocket
use ;
use ;
Multipart / Form Upload
use ;
use parse_multipart;
OpenAPI / Scalar docs
Doc comments on handlers become OpenAPI descriptions automatically:
/// Returns a greeting message.
/// Useful for healthchecks.
Environment Variables
| Variable | Default | Description |
|---|---|---|
WORKERS |
num_cpus |
Number of worker threads |
PORT |
8080 |
Listening port |
CHOPIN_SLAB_CAPACITY |
10000 |
Max simultaneous connections per worker |
CHOPIN_EPOLL_TIMEOUT_MS |
1000 |
epoll wait timeout (ms). Set 0 for spin-poll (lowest latency, higher CPU) |
Modules
| Module | Description |
|---|---|
server |
Server (low-level) and Chopin (macro-driven) builders |
router |
Trie-based router with O(1) static fast-table |
worker |
Per-thread epoll/kqueue + io_uring event loop |
http |
Request, Response, Body, Method, Context |
parser |
Zero-copy HTTP/1.1 request parser |
conn |
Connection state machine and slab slot |
slab |
Fixed-capacity connection pool (no malloc in accept path) |
timer |
Hashed timing wheel for keep-alive timeouts |
websocket |
RFC 6455 WebSocket frame encode/decode |
multipart |
RFC 7578 multipart/form-data parser |
http2 |
HTTP/2 frame primitives |
openapi |
OpenAPI 3.1 spec generation + Scalar UI handler |
extract |
FromRequest trait, Json<T>, Query<T> extractors |
headers |
Compact inline header store |
syscalls |
Raw epoll, kqueue, SO_REUSEPORT, sendfile, writev wrappers |
License
MIT © kowito