cztop 1.3.1 → 2.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +99 -0
- data/CLAUDE.md +39 -0
- data/Gemfile +0 -4
- data/README.md +90 -179
- data/ZGUIDE_SUMMARY.md +1111 -0
- data/cztop.gemspec +6 -7
- data/lib/cztop/curve/auth.rb +100 -0
- data/lib/cztop/curve.rb +126 -0
- data/lib/cztop/ffi.rb +489 -0
- data/lib/cztop/has_ffi_delegate.rb +20 -9
- data/lib/cztop/monitor.rb +88 -87
- data/lib/cztop/socket/dealer.rb +28 -0
- data/lib/cztop/socket/fd_wait.rb +88 -0
- data/lib/cztop/socket/pair.rb +28 -0
- data/lib/cztop/socket/pub.rb +27 -0
- data/lib/cztop/socket/pull.rb +27 -0
- data/lib/cztop/socket/push.rb +27 -0
- data/lib/cztop/socket/readable.rb +76 -0
- data/lib/cztop/socket/rep.rb +28 -0
- data/lib/cztop/socket/req.rb +28 -0
- data/lib/cztop/socket/router.rb +38 -0
- data/lib/cztop/socket/stream.rb +29 -0
- data/lib/cztop/socket/sub.rb +50 -0
- data/lib/cztop/socket/types.rb +2 -341
- data/lib/cztop/socket/writable.rb +86 -0
- data/lib/cztop/socket/xpub.rb +28 -0
- data/lib/cztop/socket/xsub.rb +28 -0
- data/lib/cztop/socket.rb +94 -27
- data/lib/cztop/version.rb +1 -1
- data/lib/cztop/zsock_options.rb +333 -364
- data/lib/cztop.rb +28 -48
- metadata +32 -55
- data/lib/cztop/actor.rb +0 -340
- data/lib/cztop/authenticator.rb +0 -113
- data/lib/cztop/beacon.rb +0 -117
- data/lib/cztop/cert_store.rb +0 -65
- data/lib/cztop/certificate.rb +0 -234
- data/lib/cztop/config/comments.rb +0 -77
- data/lib/cztop/config/serialization.rb +0 -102
- data/lib/cztop/config/traversing.rb +0 -188
- data/lib/cztop/config.rb +0 -135
- data/lib/cztop/frame.rb +0 -193
- data/lib/cztop/message/frames.rb +0 -88
- data/lib/cztop/message.rb +0 -220
- data/lib/cztop/metadata.rb +0 -111
- data/lib/cztop/poller/aggregated.rb +0 -142
- data/lib/cztop/poller/zmq.rb +0 -92
- data/lib/cztop/poller/zpoller.rb +0 -125
- data/lib/cztop/poller.rb +0 -245
- data/lib/cztop/polymorphic_zsock_methods.rb +0 -32
- data/lib/cztop/proxy.rb +0 -164
- data/lib/cztop/send_receive_methods.rb +0 -171
- data/lib/cztop/z85/padded.rb +0 -107
- data/lib/cztop/z85/pipe.rb +0 -200
- data/lib/cztop/z85.rb +0 -90
- data/lib/cztop/zap.rb +0 -259
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: de1d34e78550eaaaa2397a9bc1d1a29a57e36ef00d573a30e68b3903f8e1e43c
|
|
4
|
+
data.tar.gz: a9e4522e743b7dae26358acdcfb003fe12a15d5357654b6e32909c7e7ad5bf34
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b81a176e6020b002abd3425bc66781e5eb7fdf3d907649139ffacfc7e7b1b12a17498e769dbb90fb13c29bbfe8d5d44ef8d73fa4446bb80613f9aaf159ca0eff
|
|
7
|
+
data.tar.gz: ebd44ce64395ddf965682392f7c719bc94fc4ae4277da5340c35b7cd2f9bf8c0206cb92f29fb2350ba6804de244b1c1d3df37d2359c4f391210bfb0e3626688f
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,102 @@
|
|
|
1
|
+
2.0.0.rc1
|
|
2
|
+
-----
|
|
3
|
+
|
|
4
|
+
### Breaking changes
|
|
5
|
+
|
|
6
|
+
* **Removed classes:** Actor, Authenticator, Beacon, Certificate, CertStore, Config,
|
|
7
|
+
Frame, Message, Metadata, Monitor, Poller, Proxy, Z85, ZAP
|
|
8
|
+
* **Removed modules:** SendReceiveMethods, PolymorphicZsockMethods
|
|
9
|
+
* **Removed socket types (draft API dropped):** SERVER, CLIENT, RADIO, DISH,
|
|
10
|
+
GATHER, SCATTER
|
|
11
|
+
* **Removed CURVE/PLAIN/GSSAPI security API:**
|
|
12
|
+
- `Socket#CURVE_server!`, `Socket#CURVE_client!`
|
|
13
|
+
- CURVE option methods (`#CURVE_server?`, `#CURVE_serverkey`,
|
|
14
|
+
`#CURVE_secretkey`, `#CURVE_publickey`, etc.)
|
|
15
|
+
- PLAIN option methods (`#PLAIN_server?`, `#PLAIN_username`,
|
|
16
|
+
`#PLAIN_password`, etc.)
|
|
17
|
+
- `#mechanism`, `#zap_domain`
|
|
18
|
+
* **Send/receive API changed:**
|
|
19
|
+
- `#receive` now returns `Array<String>` (was `CZTop::Message`)
|
|
20
|
+
- `#<<` accepts `String` or `Array<String>` directly (was `Message.coerce`)
|
|
21
|
+
- `#send` is the primary method; `#<<` is an alias (note: `#send` shadows
|
|
22
|
+
`Object#send`; use `__send__` for Ruby dispatch)
|
|
23
|
+
- `SendReceiveMethods` split into `Socket::Readable`, `Socket::Writable`, and
|
|
24
|
+
`Socket::FdWait` mixins; socket types include only what they need
|
|
25
|
+
(e.g. PUB includes only Writable, SUB only Readable)
|
|
26
|
+
* **Time-based options now use seconds** (was milliseconds) — applies to
|
|
27
|
+
`#recv_timeout`, `#send_timeout`, `#linger`, `#heartbeat_ivl`, `#heartbeat_ttl`,
|
|
28
|
+
`#heartbeat_timeout`, `#reconnect_ivl`
|
|
29
|
+
* **Sentinel values changed from -1 to nil:**
|
|
30
|
+
- `#recv_timeout` / `#send_timeout` — returns/accepts `nil` instead
|
|
31
|
+
of `-1` for "no timeout"
|
|
32
|
+
- `#linger` — `nil` instead of `-1` for "wait indefinitely"
|
|
33
|
+
- `#heartbeat_timeout` — `nil` instead of `-1` for "use IVL"
|
|
34
|
+
- `#reconnect_ivl` — `nil` instead of `-1` for "disabled"
|
|
35
|
+
* **`Socket::SUB#initialize` subscription is now a `prefix:` kwarg** — was a
|
|
36
|
+
positional parameter; defaults to `EVERYTHING` (`''`), pass `prefix: nil` to
|
|
37
|
+
skip subscribing
|
|
38
|
+
* **`#set_unbounded` moved from PolymorphicZsockMethods to Socket**
|
|
39
|
+
* **`OptionsAccessor` removed** — all option methods now live directly on
|
|
40
|
+
`Socket` (e.g. `socket.sndhwm` instead of `socket.options.sndhwm`)
|
|
41
|
+
* **`#rcvtimeo` / `#sndtimeo` removed** — use `#recv_timeout` / `#send_timeout`
|
|
42
|
+
(aliased as `#read_timeout` / `#write_timeout`). `nil` = no timeout
|
|
43
|
+
(block forever), `0` = nonblocking, positive = timeout in seconds.
|
|
44
|
+
* **Fuzzy `#[]` / `#[]=` accessors removed**
|
|
45
|
+
* **`czmq-ffi-gen` gem dependency removed** — replaced with handcrafted FFI
|
|
46
|
+
bindings in `lib/cztop/ffi.rb`
|
|
47
|
+
* **Minimum Ruby version raised to 3.3**
|
|
48
|
+
|
|
49
|
+
### New features
|
|
50
|
+
|
|
51
|
+
* **`CZTop::Monitor`** — socket event monitoring via CZMQ's zmonitor actor;
|
|
52
|
+
detects CONNECTED, LISTENING, ACCEPTED, DISCONNECTED, and other ZMQ events.
|
|
53
|
+
Returns `Monitor::Event` value objects (`Data.define(:name, :endpoint, :peer_address)`)
|
|
54
|
+
* **`Cztop` module alias** — `Cztop = CZTop` for conventional Ruby naming;
|
|
55
|
+
both `Cztop::Socket::REQ` and `CZTop::Socket::REQ` work
|
|
56
|
+
* **`.bind` and `.connect` class methods** on all socket types —
|
|
57
|
+
`REP.bind(endpoint)` and `REQ.connect(endpoint)` as shorthand for
|
|
58
|
+
`new(nil).tap { |s| s.bind(endpoint) }`; passes through `curve:`,
|
|
59
|
+
`prefix:` (SUB), and other kwargs
|
|
60
|
+
* **CURVE encryption** with ergonomic `curve:` kwarg on all socket constructors:
|
|
61
|
+
- `CZTop::CURVE.keypair` — generate keypairs (32-byte binary)
|
|
62
|
+
- `CZTop::CURVE.public_key(secret_key)` — derive public from secret
|
|
63
|
+
- `CZTop::CURVE.z85_encode` / `.z85_decode` — Z85 utility for interop
|
|
64
|
+
- `CZTop::CURVE::Auth` — in-memory ZAP handler (no filesystem, no zauth actor)
|
|
65
|
+
- Server: `CZTop::Socket::REP.new(endpoint, curve: { secret_key: sk })`
|
|
66
|
+
- Client: `CZTop::Socket::REQ.new(endpoint, curve: { secret_key: sk, server_key: pk })`
|
|
67
|
+
* **`@`/`>` endpoint prefix convention** supported on all socket constructors
|
|
68
|
+
(e.g. `PAIR.new("@inproc://ep")` to bind, `PAIR.new(">inproc://ep")` to connect)
|
|
69
|
+
* **New socket options:**
|
|
70
|
+
- `#reconnect_ivl_max` — max reconnect backoff interval (exponential backoff)
|
|
71
|
+
- `#max_msg_size` — max inbound message size (DoS protection)
|
|
72
|
+
- `#immediate?` / `#immediate=` — queue only for completed connections
|
|
73
|
+
- `#conflate?` / `#conflate=` — keep only last message (last-value-cache)
|
|
74
|
+
- `#tcp_keepalive` / `#tcp_keepalive_idle` / `#tcp_keepalive_cnt` /
|
|
75
|
+
`#tcp_keepalive_intvl` — TCP keepalive tuning
|
|
76
|
+
|
|
77
|
+
### Other changes
|
|
78
|
+
|
|
79
|
+
* **FFI bindings for zactor, zstr, zsock_wait** — foundational bindings for
|
|
80
|
+
CZMQ actor-based APIs (used by Monitor, extensible for future actors)
|
|
81
|
+
* replace old examples with numbered `examples/zguide/` pattern files
|
|
82
|
+
(01–12: req/rep, pub/sub, pipeline, lazy pirate, heartbeat, LVC, clone,
|
|
83
|
+
majordomo, titanic, binary star, freelance)
|
|
84
|
+
* expand ZGUIDE_SUMMARY.md to ~30 min read with working code excerpts,
|
|
85
|
+
threading/concurrency guidance, and common mistakes section
|
|
86
|
+
* replace RSpec with Minitest
|
|
87
|
+
* replace `perf/` with `bench/` using benchmark-ips
|
|
88
|
+
* add per-socket-type integration test files for all 13 types
|
|
89
|
+
* add socket combination tests (ROUTER+REQ, ROUTER+ROUTER, pipeline, XPUB+multi SUB)
|
|
90
|
+
* add HWM mute state tests (PUSH/PULL blocking, PUB/SUB dropping, ROUTER mandatory)
|
|
91
|
+
* add REQ/REP reconnection tests (TCP restart, stuck-state demonstration)
|
|
92
|
+
* add STREAM ↔ raw TCP integration tests
|
|
93
|
+
* add CURVE throughput benchmark (`bench/threads/curve_throughput.rb`)
|
|
94
|
+
* add Shannon entropy system tests for CURVE (`test/system/`)
|
|
95
|
+
* split socket creation from connect/bind to support pre-connect option setting
|
|
96
|
+
* tune FD_TIMEOUT (500ms → 250ms) and JIFFY (15ms → 1ms) for better responsiveness
|
|
97
|
+
* fix zmq_errno race condition in `#raise_zmq_err`
|
|
98
|
+
* move CZMQ signal handler disabling into `lib/cztop/ffi.rb`
|
|
99
|
+
|
|
1
100
|
1.3.2 (1/3/2025)
|
|
2
101
|
-----
|
|
3
102
|
* add 'benchmark' dependency for specs
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# CZTop
|
|
2
|
+
|
|
3
|
+
Ruby FFI binding for CZMQ/ZMQ. Version 2.0.0.pre1. Requires Ruby >= 3.3.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
- `lib/cztop/socket.rb` — Socket base class (connect, bind, etc.)
|
|
8
|
+
- `lib/cztop/socket/fd_wait.rb` — `FdWait` mixin: FD polling infrastructure (`FD_TIMEOUT`, `JIFFY`, `#wait_for_fd_signal`, `#wait_for_socket_state`)
|
|
9
|
+
- `lib/cztop/socket/readable.rb` — `Readable` mixin: `#receive` → `Array<String>`, `#wait_readable`, `#read_timeout`
|
|
10
|
+
- `lib/cztop/socket/writable.rb` — `Writable` mixin: `#send` accepts `String`/`Array<String>`, `#<<`, `#wait_writable`, `#write_timeout`
|
|
11
|
+
- `lib/cztop/socket/types.rb` — `Types` constants + `TypeNames`
|
|
12
|
+
- `lib/cztop/socket/{req,rep,dealer,router,pub,sub,xpub,xsub,push,pull,pair,stream}.rb` — individual socket types
|
|
13
|
+
- `lib/cztop/ffi.rb` — FFI bindings (zsock, zmsg, zframe, zstr) + CZMQ signal handler disabling
|
|
14
|
+
- `bench/` — benchmark-ips scripts (async/threads × throughput/latency)
|
|
15
|
+
|
|
16
|
+
### ZMQ FD polling
|
|
17
|
+
|
|
18
|
+
ZMQ uses a single edge-triggered FD for both read/write signaling. `#wait_for_socket_state`
|
|
19
|
+
checks socket readiness first (fast path via `#readable?`/`#writable?`), then polls the FD.
|
|
20
|
+
|
|
21
|
+
- `FD_TIMEOUT` (250ms) — max time in `IO#wait_readable` per loop iteration; safety net for missed edges
|
|
22
|
+
- `JIFFY` (1ms) — sleep after false wakeup (FD signals but socket not ready)
|
|
23
|
+
- Edge misses are rare (~0.2% of calls in ipc/tcp req/rep), never in inproc throughput
|
|
24
|
+
- `IO#wait_readable` is interruptible by signals — Ctrl-C works immediately
|
|
25
|
+
- `__send__` used instead of `send` to avoid clash with ZMQ `#send` method
|
|
26
|
+
- Socket types include only the mixins they need (e.g. PUB includes only Writable, SUB only Readable)
|
|
27
|
+
|
|
28
|
+
### Tuning rationale
|
|
29
|
+
|
|
30
|
+
- JIFFY 15ms→1ms: each edge miss stalls for full JIFFY duration; 1ms reduces impact 15x
|
|
31
|
+
- FD_TIMEOUT 500ms→250ms: halves worst-case stall; no measurable perf impact since FD signals correctly 99.8% of the time
|
|
32
|
+
- Measured with `bench/jiffy_sweep.rb`, `bench/fd_timeout_sweep.rb`, `bench/edge_miss_count.rb`
|
|
33
|
+
|
|
34
|
+
## Benchmarking
|
|
35
|
+
|
|
36
|
+
- Uses benchmark-ips with `warmup: 1, time: 3`
|
|
37
|
+
- Run benchmarks sequentially to reduce variance
|
|
38
|
+
- For parameter sweeps: test multiple values in a single script with 3 runs each, report median
|
|
39
|
+
- Sister project **rbnng** (`/home/roadster/dev/oss/rbnng`) has identical bench structure for comparison
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,224 +1,135 @@
|
|
|
1
|
-

|
|
2
|
-

|
|
3
|
-

|
|
4
|
-
[](https://codecov.io/gh/paddor/cztop)
|
|
5
|
-
|
|
6
1
|
# CZTop
|
|
7
2
|
|
|
8
|
-
|
|
9
|
-
[
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
mechanisms (like CURVE).
|
|
3
|
+
[](https://github.com/paddor/cztop/actions/workflows/ci.yml)
|
|
4
|
+
[](https://rubygems.org/gems/cztop)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.ruby-lang.org)
|
|
13
7
|
|
|
8
|
+
Ruby FFI binding for [CZMQ](http://czmq.zeromq.org/) / [ZeroMQ](https://zeromq.org/) — high-performance asynchronous messaging for distributed systems.
|
|
14
9
|
|
|
15
|
-
|
|
10
|
+
> **353k msg/s** inproc throughput | **49 µs** fiber roundtrip latency | nonblock fast path
|
|
16
11
|
|
|
17
|
-
|
|
12
|
+
---
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
#! /usr/bin/env ruby
|
|
14
|
+
## Highlights
|
|
21
15
|
|
|
22
|
-
|
|
16
|
+
- **All socket types** — req/rep, pub/sub, push/pull, dealer/router, xpub/xsub, pair, stream
|
|
17
|
+
- **Async-first** — first-class [async](https://github.com/socketry/async) fiber support, also works with plain threads
|
|
18
|
+
- **Ruby-idiomatic API** — messages as `Array<String>`, errors as exceptions, timeouts as `IO::TimeoutError`
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
source 'https://rubygems.org'
|
|
26
|
-
gem 'cztop', path: '../../'
|
|
27
|
-
gem 'async'
|
|
28
|
-
end
|
|
20
|
+
## Install
|
|
29
21
|
|
|
30
|
-
|
|
31
|
-
# ENDPOINT = 'ipc:///tmp/req_rep_example0'
|
|
32
|
-
# ENDPOINT = 'tcp://localhost:5556'
|
|
22
|
+
Install CZMQ on your system:
|
|
33
23
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
loop do
|
|
39
|
-
msg = socket.receive
|
|
40
|
-
puts "<<< #{msg.to_a.inspect}"
|
|
41
|
-
socket << msg.to_a.map(&:upcase)
|
|
42
|
-
end
|
|
43
|
-
ensure
|
|
44
|
-
puts "REP done."
|
|
45
|
-
end
|
|
24
|
+
```sh
|
|
25
|
+
# Debian/Ubuntu
|
|
26
|
+
sudo apt install libczmq-dev
|
|
46
27
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
10.times do |i|
|
|
51
|
-
socket << "foobar ##{i}"
|
|
52
|
-
msg = socket.receive
|
|
53
|
-
puts ">>> #{msg.to_a.inspect}"
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
puts "REQ done."
|
|
57
|
-
rep_task.stop
|
|
58
|
-
end
|
|
59
|
-
end
|
|
28
|
+
# macOS
|
|
29
|
+
brew install czmq
|
|
60
30
|
```
|
|
61
31
|
|
|
32
|
+
Then add the gem:
|
|
62
33
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
<<< ["foobar #0"]
|
|
68
|
-
>>> ["FOOBAR #0"]
|
|
69
|
-
<<< ["foobar #1"]
|
|
70
|
-
>>> ["FOOBAR #1"]
|
|
71
|
-
<<< ["foobar #2"]
|
|
72
|
-
>>> ["FOOBAR #2"]
|
|
73
|
-
<<< ["foobar #3"]
|
|
74
|
-
>>> ["FOOBAR #3"]
|
|
75
|
-
<<< ["foobar #4"]
|
|
76
|
-
>>> ["FOOBAR #4"]
|
|
77
|
-
<<< ["foobar #5"]
|
|
78
|
-
>>> ["FOOBAR #5"]
|
|
79
|
-
<<< ["foobar #6"]
|
|
80
|
-
>>> ["FOOBAR #6"]
|
|
81
|
-
<<< ["foobar #7"]
|
|
82
|
-
>>> ["FOOBAR #7"]
|
|
83
|
-
<<< ["foobar #8"]
|
|
84
|
-
>>> ["FOOBAR #8"]
|
|
85
|
-
<<< ["foobar #9"]
|
|
86
|
-
>>> ["FOOBAR #9"]
|
|
87
|
-
REQ done.
|
|
88
|
-
REP done.
|
|
89
|
-
|
|
90
|
-
________________________________________________________
|
|
91
|
-
Executed in 401.51 millis fish external
|
|
92
|
-
usr time 308.44 millis 605.00 micros 307.83 millis
|
|
93
|
-
sys time 40.08 millis 278.00 micros 39.81 millis
|
|
94
|
-
|
|
34
|
+
```sh
|
|
35
|
+
gem install cztop
|
|
36
|
+
# or in Gemfile
|
|
37
|
+
gem 'cztop'
|
|
95
38
|
```
|
|
96
39
|
|
|
97
|
-
|
|
40
|
+
## Quick Start
|
|
98
41
|
|
|
99
|
-
|
|
42
|
+
### Request / Reply
|
|
100
43
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
* compatible with Fiber Scheduler (only on Ruby >= 3.2)
|
|
105
|
-
* errors as exceptions
|
|
106
|
-
* CURVE security
|
|
107
|
-
* supports CZMQ DRAFT API
|
|
108
|
-
* extensive spec coverage
|
|
44
|
+
```ruby
|
|
45
|
+
require 'cztop'
|
|
46
|
+
require 'async'
|
|
109
47
|
|
|
110
|
-
|
|
48
|
+
Async do |task|
|
|
49
|
+
rep = CZTop::Socket::REP.new('inproc://example')
|
|
50
|
+
req = CZTop::Socket::REQ.new('inproc://example')
|
|
111
51
|
|
|
52
|
+
task.async do
|
|
53
|
+
msg = rep.receive
|
|
54
|
+
rep << msg.map(&:upcase)
|
|
55
|
+
end
|
|
112
56
|
|
|
113
|
-
|
|
114
|
-
|
|
57
|
+
req << 'hello'
|
|
58
|
+
puts req.receive.inspect # => ["HELLO"]
|
|
59
|
+
end
|
|
60
|
+
```
|
|
115
61
|
|
|
62
|
+
### Pub / Sub
|
|
116
63
|
|
|
117
|
-
|
|
64
|
+
```ruby
|
|
65
|
+
Async do |task|
|
|
66
|
+
pub = CZTop::Socket::PUB.new('inproc://pubsub')
|
|
67
|
+
sub = CZTop::Socket::SUB.new('inproc://pubsub')
|
|
68
|
+
sub.subscribe('') # subscribe to all
|
|
118
69
|
|
|
119
|
-
|
|
70
|
+
sleep 0.01 # allow connection to establish
|
|
120
71
|
|
|
121
|
-
|
|
72
|
+
task.async { pub << 'news flash' }
|
|
73
|
+
puts sub.receive.inspect # => ["news flash"]
|
|
74
|
+
end
|
|
75
|
+
```
|
|
122
76
|
|
|
123
|
-
|
|
77
|
+
### Push / Pull (Pipeline)
|
|
124
78
|
|
|
125
|
-
|
|
79
|
+
```ruby
|
|
80
|
+
Async do
|
|
81
|
+
push = CZTop::Socket::PUSH.new('inproc://pipeline')
|
|
82
|
+
pull = CZTop::Socket::PULL.new('inproc://pipeline')
|
|
126
83
|
|
|
127
|
-
|
|
84
|
+
push << 'work item'
|
|
85
|
+
puts pull.receive.inspect # => ["work item"]
|
|
86
|
+
end
|
|
87
|
+
```
|
|
128
88
|
|
|
129
|
-
|
|
89
|
+
## Socket Types
|
|
130
90
|
|
|
131
|
-
|
|
91
|
+
| Pattern | Classes | Direction |
|
|
92
|
+
|---------|---------|-----------|
|
|
93
|
+
| Request/Reply | `REQ`, `REP` | bidirectional |
|
|
94
|
+
| Publish/Subscribe | `PUB`, `SUB`, `XPUB`, `XSUB` | unidirectional |
|
|
95
|
+
| Pipeline | `PUSH`, `PULL` | unidirectional |
|
|
96
|
+
| Routing | `DEALER`, `ROUTER` | bidirectional |
|
|
97
|
+
| Exclusive pair | `PAIR` | bidirectional |
|
|
98
|
+
| Raw TCP | `STREAM` | bidirectional |
|
|
132
99
|
|
|
133
|
-
|
|
100
|
+
All classes live under `CZTop::Socket::`.
|
|
134
101
|
|
|
135
|
-
|
|
136
|
-
gem 'cztop'
|
|
137
|
-
```
|
|
102
|
+
## Performance
|
|
138
103
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
$ bundle
|
|
142
|
-
|
|
143
|
-
Or install it yourself as:
|
|
144
|
-
|
|
145
|
-
$ gem install cztop
|
|
146
|
-
|
|
147
|
-
### Class Hierarchy
|
|
148
|
-
|
|
149
|
-
Here's an overview of the core classes:
|
|
150
|
-
|
|
151
|
-
* [CZTop](http://www.rubydoc.info/gems/cztop/CZTop)
|
|
152
|
-
* [Actor](http://www.rubydoc.info/gems/cztop/CZTop)
|
|
153
|
-
* [Authenticator](http://www.rubydoc.info/gems/cztop/CZTop/Authenticator)
|
|
154
|
-
* [Beacon](http://www.rubydoc.info/gems/cztop/CZTop/Beacon)
|
|
155
|
-
* [Certificate](http://www.rubydoc.info/gems/cztop/CZTop/Certificate)
|
|
156
|
-
* [CertStore](http://www.rubydoc.info/gems/cztop/CZTop/CertStore)
|
|
157
|
-
* [Config](http://www.rubydoc.info/gems/cztop/CZTop/Config)
|
|
158
|
-
* [Frame](http://www.rubydoc.info/gems/cztop/CZTop/Frame)
|
|
159
|
-
* [Message](http://www.rubydoc.info/gems/cztop/CZTop/Message)
|
|
160
|
-
* [Monitor](http://www.rubydoc.info/gems/cztop/CZTop/Monitor)
|
|
161
|
-
* [Metadata](http://www.rubydoc.info/gems/cztop/CZTop/Metadata)
|
|
162
|
-
* [Proxy](http://www.rubydoc.info/gems/cztop/CZTop/Proxy)
|
|
163
|
-
* [Poller](http://www.rubydoc.info/gems/cztop/CZTop/Poller) (based on `zmq_poller_*()` functions)
|
|
164
|
-
* [Aggregated](http://www.rubydoc.info/gems/cztop/CZTop/Poller/Aggregated)
|
|
165
|
-
* [ZPoller](http://www.rubydoc.info/gems/cztop/CZTop/Poller/ZPoller)
|
|
166
|
-
* [Socket](http://www.rubydoc.info/gems/cztop/CZTop/Socket)
|
|
167
|
-
* [REQ](http://www.rubydoc.info/gems/cztop/CZTop/Socket/REQ) < Socket
|
|
168
|
-
* [REP](http://www.rubydoc.info/gems/cztop/CZTop/Socket/REP) < Socket
|
|
169
|
-
* [ROUTER](http://www.rubydoc.info/gems/cztop/CZTop/Socket/ROUTER) < Socket
|
|
170
|
-
* [DEALER](http://www.rubydoc.info/gems/cztop/CZTop/Socket/DEALER) < Socket
|
|
171
|
-
* [PUSH](http://www.rubydoc.info/gems/cztop/CZTop/Socket/PUSH) < Socket
|
|
172
|
-
* [PULL](http://www.rubydoc.info/gems/cztop/CZTop/Socket/PULL) < Socket
|
|
173
|
-
* [PUB](http://www.rubydoc.info/gems/cztop/CZTop/Socket/PUB) < Socket
|
|
174
|
-
* [SUB](http://www.rubydoc.info/gems/cztop/CZTop/Socket/SUB) < Socket
|
|
175
|
-
* [XPUB](http://www.rubydoc.info/gems/cztop/CZTop/Socket/XPUB) < Socket
|
|
176
|
-
* [XSUB](http://www.rubydoc.info/gems/cztop/CZTop/Socket/XSUB) < Socket
|
|
177
|
-
* [PAIR](http://www.rubydoc.info/gems/cztop/CZTop/Socket/PAIR) < Socket
|
|
178
|
-
* [STREAM](http://www.rubydoc.info/gems/cztop/CZTop/Socket/STREAM) < Socket
|
|
179
|
-
* [CLIENT](http://www.rubydoc.info/gems/cztop/CZTop/Socket/CLIENT) < Socket
|
|
180
|
-
* [SERVER](http://www.rubydoc.info/gems/cztop/CZTop/Socket/SERVER) < Socket
|
|
181
|
-
* [RADIO](http://www.rubydoc.info/gems/cztop/CZTop/Socket/RADIO) < Socket
|
|
182
|
-
* [DISH](http://www.rubydoc.info/gems/cztop/CZTop/Socket/DISH) < Socket
|
|
183
|
-
* [SCATTER](http://www.rubydoc.info/gems/cztop/CZTop/Socket/SCATTER) < Socket
|
|
184
|
-
* [GATHER](http://www.rubydoc.info/gems/cztop/CZTop/Socket/GATHER) < Socket
|
|
185
|
-
* [Z85](http://www.rubydoc.info/gems/cztop/CZTop/Z85)
|
|
186
|
-
* [Padded](http://www.rubydoc.info/gems/cztop/CZTop/Z85/Padded) < Z85
|
|
187
|
-
* [Pipe](http://www.rubydoc.info/gems/cztop/CZTop/Z85/Pipe)
|
|
188
|
-
* [ZAP](http://www.rubydoc.info/gems/cztop/CZTop/ZAP)
|
|
189
|
-
|
|
190
|
-
More information in the [API documentation](http://www.rubydoc.info/github/paddor/cztop).
|
|
191
|
-
|
|
192
|
-
## Documentation
|
|
193
|
-
|
|
194
|
-
The API should be fairly straight-forward to anyone who is familiar with CZMQ
|
|
195
|
-
and Ruby. The following API documentation is currently available:
|
|
196
|
-
|
|
197
|
-
* [YARD API documentation](http://www.rubydoc.info/gems/cztop) (release)
|
|
198
|
-
|
|
199
|
-
Feel free to start a [wiki](https://github.com/paddor/cztop/wiki) page.
|
|
104
|
+
Benchmarked with benchmark-ips on Linux x86_64 (CZMQ 4.2.1, ZMQ 4.3.5, Ruby 4.0.1 +YJIT):
|
|
200
105
|
|
|
201
|
-
|
|
106
|
+
#### Throughput (push/pull)
|
|
202
107
|
|
|
203
|
-
|
|
108
|
+
| | inproc | ipc | tcp |
|
|
109
|
+
|---|--------|-----|-----|
|
|
110
|
+
| **Async** | 284k/s | 17k/s | 14k/s |
|
|
111
|
+
| **Threads** | 353k/s | 25k/s | 21k/s |
|
|
204
112
|
|
|
205
|
-
|
|
206
|
-
[perf](https://github.com/paddor/cztop/blob/master/perf) directory for latency
|
|
207
|
-
and throughput measurement scripts.
|
|
113
|
+
#### Latency (req/rep roundtrip)
|
|
208
114
|
|
|
209
|
-
|
|
115
|
+
| | inproc | ipc | tcp |
|
|
116
|
+
|---|--------|-----|-----|
|
|
117
|
+
| **Async** | 49 µs | 100 µs | 107 µs |
|
|
118
|
+
| **Threads** | 113 µs | 154 µs | 168 µs |
|
|
210
119
|
|
|
211
|
-
See
|
|
120
|
+
Async fibers deliver 2.3x lower inproc latency thanks to cheap context switching. See [`bench/`](bench/) for full results and scripts.
|
|
212
121
|
|
|
122
|
+
## API Reference
|
|
213
123
|
|
|
214
|
-
|
|
124
|
+
Full [API documentation](http://www.rubydoc.info/gems/cztop).
|
|
215
125
|
|
|
216
|
-
|
|
126
|
+
## Development
|
|
217
127
|
|
|
218
|
-
|
|
219
|
-
|
|
128
|
+
```sh
|
|
129
|
+
bundle install
|
|
130
|
+
bundle exec rake
|
|
131
|
+
```
|
|
220
132
|
|
|
221
133
|
## License
|
|
222
134
|
|
|
223
|
-
|
|
224
|
-
See the [LICENSE](https://github.com/paddor/cztop/blob/master/LICENSE) file.
|
|
135
|
+
[ISC](LICENSE)
|