Skip to content

Commit 1bb8e7e

Browse files
committed
v0.20.0
1 parent 5fc8d42 commit 1bb8e7e

4 files changed

Lines changed: 38 additions & 38 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Changelog
22

3-
## Unreleased
3+
## 0.20.0 — 2026-04-14
44

55
### Changed
66

DESIGN.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ exists to handle the reality that none of this is true:
2020
| Topology doesn't change | Bind/connect separation; peers come and go freely |
2121
| There is one administrator | No broker required; any topology works peer-to-peer |
2222
| Transport cost is zero | Batched writes reduce syscalls; inproc skips the kernel |
23-
| The network is homogeneous | ZMTP is a wire protocol; interop with libzmq, nanomsg, etc. |
23+
| The network is homogeneous | ZMTP is a wire protocol; interop with libzmq, pyzmq, CZMQ, zmq.rs |
2424

2525
OMQ brings all of this to Ruby without C extensions or FFI.
2626

@@ -163,7 +163,9 @@ so racing pumps can't double-fire side effects.
163163

164164
**Linger.** On close, send queues are drained for up to `linger` seconds.
165165
If no peers are connected, listeners stay open so late-arriving peers can
166-
still receive queued messages. `linger=0` closes immediately.
166+
still receive queued messages. The default is `Float::INFINITY` (matches
167+
libzmq: wait forever). `linger=0` closes immediately, dropping anything
168+
still queued.
167169

168170
**Reconnect.** Failed or lost connections are retried with configurable
169171
interval (default 100ms). Supports exponential backoff via a Range
@@ -248,9 +250,10 @@ Under light load, batch size is 1 -- no overhead. Under burst load (producer
248250
faster than consumer), the batch grows and flushes are amortized:
249251
`N_msgs * N_conns` syscalls become `N_conns` per cycle.
250252

251-
io-stream auto-flushes its write buffer at 64 KB, so large batches hit the
252-
wire naturally during the write loop. The explicit flush at the end only
253-
pushes the remainder that didn't fill a buffer.
253+
io-stream auto-flushes its write buffer at 256 KB (its default
254+
`MINIMUM_WRITE_SIZE`), so large batches hit the wire naturally during
255+
the write loop. The explicit flush at the end only pushes the remainder
256+
that didn't fill a buffer.
254257

255258
For fan-out (PUB/RADIO), one published message is written to all matching
256259
subscribers before flushing -- so N subscribers see 1 flush each, not N

README.md

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,32 @@
1-
# OMQWhere did the C dependency go!?
1+
# ØMQZeroMQ for Ruby, no C required
22

33
[![CI](https://github.com/zeromq/omq/actions/workflows/ci.yml/badge.svg)](https://github.com/zeromq/omq/actions/workflows/ci.yml)
44
[![Gem Version](https://img.shields.io/gem/v/omq?color=e9573f)](https://rubygems.org/gems/omq)
55
[![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](LICENSE)
66
[![Ruby](https://img.shields.io/badge/Ruby-%3E%3D%203.3-CC342D?logo=ruby&logoColor=white)](https://www.ruby-lang.org)
77

8-
`gem install omq` — that's it. No libzmq, no compiler, no system packages. Just Ruby.
9-
10-
OMQ builds ZeroMQ socket patterns on top of [protocol-zmtp](https://github.com/paddor/protocol-zmtp) (a pure Ruby [ZMTP 3.1](https://rfc.zeromq.org/spec/23/) codec) using [Async](https://github.com/socketry/async) fibers. It speaks native ZeroMQ on the wire and interoperates with libzmq, pyzmq, CZMQ, and everything else in the ZMQ ecosystem.
11-
128
> **932k msg/s** inproc | **328k msg/s** ipc | **329k msg/s** tcp
139
>
1410
> **11.5 µs** inproc latency | **54 µs** ipc | **69 µs** tcp
1511
>
1612
> Ruby 4.0 + YJIT on a Linux VM — see [`bench/`](bench/) for full results
1713
18-
---
19-
20-
## What is ZeroMQ?
21-
22-
Brokerless message-oriented middleware. No central server, no extra hop — processes talk directly to each other, cutting latency in half compared to broker-based systems. You get the patterns you'd normally build on top of RabbitMQ or Redis — pub/sub, work distribution, request/reply, fan-out — but decentralized, with no single point of failure.
23-
24-
Networking is hard. ZeroMQ abstracts away reconnection, queuing, load balancing, and framing so you can focus on what your system actually does. Start with threads talking over `inproc://`, split into processes with `ipc://`, scale across machines with `tcp://` — same code, same API, just change the URL.
14+
`gem install omq` and you're done. No libzmq, no compiler, no system packages — just Ruby talking to every other ZeroMQ peer out there.
2515

26-
If you've ever wired up services with raw TCP, HTTP polling, or Redis pub/sub and wished it was simpler, this is what you've been looking for.
16+
ØMQ gives your Ruby processes a way to talk to each other — and to anything else speaking ZeroMQ — without a broker in the middle. Same API whether they live in the same process, on the same machine, or across the network. Reconnects, queuing, and back-pressure are handled for you; you write the interesting part.
2717

28-
See [GETTING_STARTED.md](GETTING_STARTED.md) for a ~30 min walkthrough of all major patterns with working code.
18+
New to ZeroMQ? Start with [GETTING_STARTED.md](GETTING_STARTED.md) a ~30 min walkthrough of every major pattern with working code.
2919

3020
## Highlights
3121

3222
- **Zero dependencies on C** — no extensions, no FFI, no libzmq. `gem install` just works everywhere
33-
- **Fast** — YJIT-optimized hot paths, batched sends, GC-tuned allocations, buffered I/O via [io-stream](https://github.com/socketry/io-stream), direct-pipe inproc bypass.
34-
- **[`omq` CLI](https://github.com/paddor/omq-cli)**`gem install omq-cli` for a command-line tool with Ruby eval, Ractor parallelism, and script handlers
23+
- **Fast** — YJIT-optimized hot paths, batched sends, GC-tuned allocations, buffered I/O via [io-stream](https://github.com/socketry/io-stream), direct-pipe inproc bypass
24+
- **[`omq` CLI](https://github.com/paddor/omq-cli)**a powerful swiss army knife for ØMQ. `gem install omq-cli`
3525
- **Every socket pattern** — req/rep, pub/sub, push/pull, dealer/router, xpub/xsub, pair, and all draft types
3626
- **Every transport** — tcp, ipc (Unix domain sockets), inproc (in-process queues)
37-
- **Async-native** — built on fibers, non-blocking from the ground up. A shared IO thread handles sockets outside of Async — no reactor needed for simple scripts
38-
- **Wire-compatible** — interoperates with libzmq, pyzmq, CZMQ over tcp and ipc
27+
- **Async-native** — built on fibers, non-blocking from the ground up
28+
- **Works outside Async too** — a shared IO thread handles sockets for callers that aren't inside a reactor, so simple scripts just work
29+
- **Wire-compatible** — interoperates with libzmq, pyzmq, CZMQ, zmq.rs over tcp and ipc
3930
- **Bind/connect order doesn't matter** — connect before bind, bind before connect, peers come and go. ZeroMQ reconnects automatically and queued messages drain when peers arrive
4031

4132
For architecture internals, see [DESIGN.md](DESIGN.md).
@@ -164,15 +155,15 @@ All sockets are thread-safe. Default HWM is 1000 messages per socket. `max_messa
164155

165156
#### Draft (single-frame only)
166157

167-
These require the `omq-draft` gem.
158+
Each draft pattern lives in its own gem — install only the ones you use.
168159

169-
| Pattern | Send | Receive | When HWM full |
170-
|---------|------|---------|---------------|
171-
| **CLIENT** / **SERVER** | Work-stealing / routing-ID | Fair-queue | Block |
172-
| **RADIO** / **DISH** | Group fan-out | Group filter | Drop |
173-
| **SCATTER** / **GATHER** | Work-stealing | Fair-queue | Block |
174-
| **PEER** | Routing-ID | Fair-queue | Block |
175-
| **CHANNEL** | Exclusive 1-to-1 | Exclusive 1-to-1 | Block |
160+
| Pattern | Send | Receive | When HWM full | Gem |
161+
|---------|------|---------|---------------|-----|
162+
| **CLIENT** / **SERVER** | Work-stealing / routing-ID | Fair-queue | Block | [`omq-rfc-clientserver`](https://github.com/paddor/omq-rfc-clientserver) |
163+
| **RADIO** / **DISH** | Group fan-out | Group filter | Drop | [`omq-rfc-radiodish`](https://github.com/paddor/omq-rfc-radiodish) |
164+
| **SCATTER** / **GATHER** | Work-stealing | Fair-queue | Block | [`omq-rfc-scattergather`](https://github.com/paddor/omq-rfc-scattergather) |
165+
| **PEER** | Routing-ID | Fair-queue | Block | [`omq-rfc-p2p`](https://github.com/paddor/omq-rfc-p2p) |
166+
| **CHANNEL** | Exclusive 1-to-1 | Exclusive 1-to-1 | Block | [`omq-rfc-channel`](https://github.com/paddor/omq-rfc-channel) |
176167

177168
## CLI
178169

@@ -192,6 +183,12 @@ See the [omq-cli README](https://github.com/paddor/omq-cli) for full documentati
192183
- **[omq-ffi](https://github.com/paddor/omq-ffi)** — libzmq FFI backend. Same OMQ socket API, but backed by libzmq instead of the pure Ruby ZMTP stack. Useful for interop testing and when you need libzmq-specific features. Requires libzmq installed.
193184
- **[omq-ractor](https://github.com/paddor/omq-ractor)** — bridge OMQ sockets into Ruby Ractors for true parallel processing across cores. I/O stays on the main Ractor, worker Ractors do pure computation.
194185

186+
### Protocol extensions (RFCs)
187+
188+
Optional plug-ins that extend the ZMTP wire protocol. Each is a separate gem; load the ones you need.
189+
190+
- **[omq-rfc-zstd](https://github.com/paddor/omq-rfc-zstd)** — transparent Zstandard compression on the wire, negotiated per peer via READY properties.
191+
195192
## Development
196193

197194
```sh
@@ -210,16 +207,16 @@ the stack.
210207
# clone OMQ and its sibling repos into the same parent directory
211208
git clone https://github.com/paddor/omq.git
212209
git clone https://github.com/paddor/protocol-zmtp.git
213-
git clone https://github.com/paddor/nuckle.git
214-
git clone https://github.com/paddor/omq-rfc-blake3zmq.git
215-
git clone https://github.com/paddor/omq-rfc-channel.git
210+
git clone https://github.com/paddor/omq-rfc-zstd.git
216211
git clone https://github.com/paddor/omq-rfc-clientserver.git
217-
git clone https://github.com/paddor/omq-rfc-p2p.git
218-
git clone https://github.com/paddor/omq-rfc-qos.git
219212
git clone https://github.com/paddor/omq-rfc-radiodish.git
220213
git clone https://github.com/paddor/omq-rfc-scattergather.git
214+
git clone https://github.com/paddor/omq-rfc-channel.git
215+
git clone https://github.com/paddor/omq-rfc-p2p.git
216+
git clone https://github.com/paddor/omq-rfc-qos.git
221217
git clone https://github.com/paddor/omq-ffi.git
222218
git clone https://github.com/paddor/omq-ractor.git
219+
git clone https://github.com/paddor/nuckle.git
223220

224221
cd omq
225222
OMQ_DEV=1 bundle install

lib/omq/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module OMQ
4-
VERSION = "0.19.3"
4+
VERSION = "0.20.0"
55
end

0 commit comments

Comments
 (0)