8000 GitHub - paddor/omq.rs: Connect threads, processes, hosts, and languages without a broker. · GitHub
[go: up one dir, main page]

Skip to content
paddorPublic

About

Connect threads, processes, hosts, and languages without a broker.

Topics

Resources

Contributing

Security policy

Stars

147 stars

Watchers

2 watching

Forks

Latest commit

 

History

2,643 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OMQ

ZeroMQ messaging, built in Rust.

Connect threads, processes, hosts, and languages without a broker. Your application sends messages, OMQ handles the network. Queues all the way!

  • libzmq compatibility. Familiar ZeroMQ socket patterns, compatible wire protocol, and a drop-in C API.
  • High throughput, low latency. Millions of messages per second, low p99 latency, and scalable background IO. See the benchmarks.
  • Compression. LZ4 and adaptive Zstd transports save bandwidth without changing application messages.
  • One API across transports. inproc, IPC, TCP, UDP, WebSocket, QUIC, DART, and SHM. Sockets handle framing, reconnection, and back-pressure.
  • Language support. Rust plus bindings for C/C++, Python, Ruby, Go, Java, Node.js, .NET, Lua, BEAM, Zig, and Crystal. OMQ.ts is a TypeScript browser client.

Usage

Same socket types, same connect/bind/send/recv:

cargo add omq-tokio --rename omq
cargo add tokio --features macros,rt-multi-thread
use omq::{Context, Message, Options, Result, SocketType};

#[tokio::main]
async fn main() -> Result<()> {
    let ctx = Context::new();

    let pull = ctx.socket(SocketType::Pull, Options::default());
    let endpoint = pull.bind("tcp://127.0.0.1:0").await?;

    let push = ctx.socket(SocketType::Push, Options::default());
    push.connect(endpoint).await?;
    push.send(Message::single("hello")).await?;

    let msg = pull.recv().await?;
    assert_eq!(&msg[0], b"hello");
    Ok(())
}

The application can await bind, connect, send, and recv on any runtime like Tokio or Compio. OMQ handles the network on its own background IO threads. Port 0 selects a free TCP port, returned by bind().

New to ZeroMQ? Start with GETTING_STARTED.md. More examples in examples/zguide/, a port of the ZeroMQ Guide patterns to OMQ.

Performance

PUSH/PULL throughput over TCP: OMQ and libzmq

8000 REQ/REP latency

REQ/REP latency over TCP: OMQ and libzmq

PUB/SUB throughput

PUB/SUB throughput over TCP: OMQ and libzmq

Compressed PUSH/PULL throughput

LZ4 and Zstd PUSH/PULL throughput over TCP

Full compression transport benchmarks (LZ4 and Zstd)

Full comparison charts | Other protocol comparisons

Behavior under load

  • Abstraction. Connect-before-bind. Transparent reconnection. Peer failures never become send/recv errors.
  • Back-pressure. HWM limits queues. Block or drop according to socket semantics.
  • Fairness. Round-robin sends and fair-queued receives.
  • Natural batching. Internal batches coalesce wakeups and writes. No explicit batches from application needed.
  • Efficient payloads. Inline tiny messages, by-value inproc, gather writes for large payloads, opt-in buffer pools.

OMQ normally runs transport work on dedicated background IO threads, separate from application threads. Embedded and exclusive APIs are also available:

Runtime placement
API IO placement
Context::new().socket(...) OMQ-owned background IO threads, async API
Context::new().blocking_socket(...) OMQ-owned background IO threads, synchronous API
Context::current().socket(...) Existing tokio runtime
omq_tokio::exclusive::Socket::{connect, bind}(...) Caller task, one TCP peer, no socket driver task

Owned contexts support independent aggregate ingress/egress byte limits, configured before the first socket; exhaustion applies backpressure. Limits count transport bytes after compression and each fan-out copy; IPC, inproc, and SHM are excluded.

let ctx = omq::Context::new();
ctx.set_network_rate_limits(omq::NetworkRateLimits {
    ingress: None,
    egress: Some(omq::ByteRateLimit::new(10_000_000, 100_000)),
})?;

Cargo features

The default build includes the NULL mechanism and TCP / IPC / inproc / UDP, plus SHM on Linux. It needs no libzmq, libsodium, or C compiler. Optional features:

Feature Adds
plain PLAIN username/password authentication (RFC 24)
curve CURVE authentication and encryption (RFC 26)
lz4 lz4+tcp:// compression (RFC)
zstd Experimental zstd+tcp:// compression, with a level that adapts to the sender bottleneck
ws WebSocket (ws://) and verified TLS (wss://)
quic TLS-encrypted QUIC (quic://): overview, example
webtransport Browser WebTransport over HTTP/3 on quic:// listeners (RFC)
dart Reliable ordered UDP (dart://) for low latency: overview, RFC

Workspace

Seven Cargo workspace crates. The protocol core, tokio backend, and WebTransport crates forbid unsafe Rust. SHM transport and native interfaces isolate unsafe operations.

Crate What it does
omq-proto Sans-I/O ZMTP 3.x: codec, messages, mechanisms, subscriptions
omq-tokio Tokio backend for Linux, macOS, and Windows
omq-shm Linux shared-memory transport
omq-libzmq libzmq-compatible C interface (libomq_zmq dynamic/static library)
omq-bench Benchmark runner and SVG chart generator
omq-webtrans-proto, omq-webtrans-quinn WebTransport over HTTP/3, adapted from webtrans (MIT)

Language bindings:

Language Binding
C/C++ omq-libzmq: libzmq-compatible C API
Python pyomq: synchronous and asyncio APIs
Ruby omq-rs: scheduler-aware synchronous API
Go OMQ.go: goroutine-safe API
Java OMQ.java: synchronous and async APIs
Node.js OMQ.node: native addon
.NET OMQ.Net: managed wrapper
Lua OMQ.lua: native module
Erlang, Elixir, Gleam OMQ.beam: NIF and wrappers
Zig OMQ.zig: C API wrapper
Crystal omq-binding.cr: native binding

Pure implementations speak ZMTP without the Rust engine:

Language Implementation
TypeScript OMQ.ts: browser client over ws://, wss://, lz4+ws://, and WebTransport

Sister projects

  • OMQ.rb: Ruby implementation with compatible compression and an optional Rust backend.

Further reading

Platform and requirements

  • Rust 1.93 or newer (edition 2024).
  • Linux (x86_64, aarch64, i686-unknown-linux-gnu, armv7-unknown-linux-gnueabihf)
  • macOS (ARM/Intel)
  • Windows

Linux is the primary development and benchmarking platform.

Contributing

See CONTRIBUTING.md for guidelines and DEVELOPMENT.md for build and test commands, and RUNNING_BENCHMARKS.md for benchmarks.

AI disclosure

This project was built with significant LLM assistance throughout: architecture, implementation, tests, benchmark infrastructure, and docs. It's an experiment in what LLM-assisted development can and can't do. The design decisions and direction are mine.

License

ISC.

About

Connect threads, processes, hosts, and languages without a broker.

Topics

Resources

Contributing

Security policy

Stars

147 stars

Watchers

2 watching

Forks

Releases

Contributors

Languages

0