cztop 2.0.2 → 2.0.3
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 +19 -0
- data/README.md +24 -19
- data/lib/cztop/curve/auth.rb +13 -6
- data/lib/cztop/curve.rb +1 -1
- data/lib/cztop/ffi.rb +22 -13
- data/lib/cztop/monitor.rb +1 -0
- data/lib/cztop/socket/dealer.rb +1 -1
- data/lib/cztop/socket/pair.rb +1 -1
- data/lib/cztop/socket/pub.rb +1 -1
- data/lib/cztop/socket/pull.rb +1 -1
- data/lib/cztop/socket/push.rb +1 -1
- data/lib/cztop/socket/readable.rb +6 -1
- data/lib/cztop/socket/rep.rb +1 -1
- data/lib/cztop/socket/req.rb +1 -1
- data/lib/cztop/socket/router.rb +1 -1
- data/lib/cztop/socket/stream.rb +1 -1
- data/lib/cztop/socket/sub.rb +1 -1
- data/lib/cztop/socket/writable.rb +7 -5
- data/lib/cztop/socket/xpub.rb +1 -1
- data/lib/cztop/socket/xsub.rb +1 -1
- data/lib/cztop/socket.rb +1 -1
- data/lib/cztop/version.rb +1 -1
- data/lib/cztop/zsock_options.rb +9 -1
- data/lib/cztop.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f3e5938035e1b344dafa25665293cddc9017c5b9c47280bacc9fc4b9ff97fc2e
|
|
4
|
+
data.tar.gz: 16b1a7896a2f118cfd2fcfa2829acbeb5e3d021472c34aa6dfd190ed8bb1a5bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5e6058194cbb28727e78f92a431c203ee45f5363a89e4fbaa3026553d3b3b8610240947b7336f5625218458acd77388038734b00a966c8f6fa3ac7c45d9616a0
|
|
7
|
+
data.tar.gz: b549f127a5031b643807702ee279a0dc4565f252c3489b10da5f6191617162f618946518175e3bb4de4c3c7b1628fb355ad5c063f31c2b05c34bf93c07d15f2c
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
## [Unreleased]
|
|
2
|
+
|
|
3
|
+
2.0.3
|
|
4
|
+
-----
|
|
5
|
+
|
|
6
|
+
* Port specs to named `Minitest::Spec` subclasses with ordinary Ruby helpers
|
|
7
|
+
* Add regression coverage for native library loading and fallback
|
|
8
|
+
* Raise native send/receive errors immediately instead of waiting for readiness
|
|
9
|
+
* Raise `IO::EAGAINWaitReadable`/`IO::EAGAINWaitWritable` when nonblocking I/O
|
|
10
|
+
would block
|
|
11
|
+
* Convert all multipart message parts before sending the first frame
|
|
12
|
+
* Avoid an extra array allocation for scalar sends without modifying caller arrays
|
|
13
|
+
* Free native identity strings and messages retained after failed sends
|
|
14
|
+
* Reject endpoint and subscription operations on closed sockets, and receive
|
|
15
|
+
operations on closed monitors
|
|
16
|
+
* Close the CURVE authentication socket in its responder thread during shutdown
|
|
17
|
+
* Fix linger documentation to use seconds
|
|
18
|
+
* Clean up benchmark socket lifetimes and refresh measurements and README
|
|
19
|
+
|
|
1
20
|
2.0.2
|
|
2
21
|
-----
|
|
3
22
|
|
data/README.md
CHANGED
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://www.ruby-lang.org)
|
|
7
7
|
|
|
8
|
-
Ruby FFI binding for [CZMQ](
|
|
8
|
+
Ruby FFI binding for [CZMQ](https://github.com/zeromq/czmq) and [ZeroMQ](https://zeromq.org/), with support for threads, Fiber Scheduler, and CURVE encryption.
|
|
9
9
|
|
|
10
|
-
> **
|
|
10
|
+
> **310k msg/s** inproc throughput (64 B) | **61 µs** Async roundtrip latency
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
## Highlights
|
|
15
15
|
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **Ruby
|
|
16
|
+
- **Socket types:** REQ/REP, PUB/SUB, PUSH/PULL, DEALER/ROUTER, XPUB/XSUB, PAIR, STREAM
|
|
17
|
+
- **Fibers and threads:** works with [async](https://github.com/socketry/async) and plain threads
|
|
18
|
+
- **Ruby API:** messages as `Array<String>`, errors as exceptions, timeouts as `IO::TimeoutError`
|
|
19
19
|
|
|
20
20
|
## Install
|
|
21
21
|
|
|
@@ -33,17 +33,21 @@ Then add the gem:
|
|
|
33
33
|
|
|
34
34
|
```sh
|
|
35
35
|
gem install cztop
|
|
36
|
-
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or add it to your Gemfile:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
37
41
|
gem 'cztop'
|
|
38
42
|
```
|
|
39
43
|
|
|
40
44
|
## Learning ZeroMQ
|
|
41
45
|
|
|
42
|
-
New to ZeroMQ? See [ZGUIDE_SUMMARY.md](ZGUIDE_SUMMARY.md)
|
|
46
|
+
New to ZeroMQ? See [ZGUIDE_SUMMARY.md](ZGUIDE_SUMMARY.md) for messaging patterns and working CZTop examples.
|
|
43
47
|
|
|
44
48
|
## Quick Start
|
|
45
49
|
|
|
46
|
-
###
|
|
50
|
+
### REQ / REP
|
|
47
51
|
|
|
48
52
|
```ruby
|
|
49
53
|
require 'cztop'
|
|
@@ -63,7 +67,7 @@ Async do |task|
|
|
|
63
67
|
end
|
|
64
68
|
```
|
|
65
69
|
|
|
66
|
-
###
|
|
70
|
+
### PUB / SUB
|
|
67
71
|
|
|
68
72
|
```ruby
|
|
69
73
|
Async do |task|
|
|
@@ -78,7 +82,7 @@ Async do |task|
|
|
|
78
82
|
end
|
|
79
83
|
```
|
|
80
84
|
|
|
81
|
-
###
|
|
85
|
+
### PUSH / PULL (Pipeline)
|
|
82
86
|
|
|
83
87
|
```ruby
|
|
84
88
|
Async do
|
|
@@ -95,7 +99,8 @@ end
|
|
|
95
99
|
| Pattern | Classes | Direction |
|
|
96
100
|
|---------|---------|-----------|
|
|
97
101
|
| Request/Reply | `REQ`, `REP` | bidirectional |
|
|
98
|
-
| Publish/Subscribe | `PUB`, `SUB
|
|
102
|
+
| Publish/Subscribe | `PUB`, `SUB` | unidirectional |
|
|
103
|
+
| Subscription forwarding | `XPUB`, `XSUB` | bidirectional |
|
|
99
104
|
| Pipeline | `PUSH`, `PULL` | unidirectional |
|
|
100
105
|
| Routing | `DEALER`, `ROUTER` | bidirectional |
|
|
101
106
|
| Exclusive pair | `PAIR` | bidirectional |
|
|
@@ -105,23 +110,23 @@ All classes live under `CZTop::Socket::`.
|
|
|
105
110
|
|
|
106
111
|
## Performance
|
|
107
112
|
|
|
108
|
-
Benchmarked with benchmark-ips on Linux x86_64 (CZMQ 4.2.1, ZMQ 4.3.5, Ruby 4.0.
|
|
113
|
+
Benchmarked with benchmark-ips on Linux x86_64 (CZMQ 4.2.1, ZMQ 4.3.5, Ruby 4.0.6 +YJIT):
|
|
109
114
|
|
|
110
|
-
#### Throughput (
|
|
115
|
+
#### Throughput (PUSH/PULL, 64 B messages)
|
|
111
116
|
|
|
112
117
|
| | inproc | ipc | tcp |
|
|
113
118
|
|---|--------|-----|-----|
|
|
114
|
-
| **Async** |
|
|
115
|
-
| **Threads** |
|
|
119
|
+
| **Async** | 278k/s | 18.3k/s | 15.8k/s |
|
|
120
|
+
| **Threads** | 310k/s | 18.3k/s | 16.2k/s |
|
|
116
121
|
|
|
117
|
-
#### Latency (
|
|
122
|
+
#### Latency (REQ/REP roundtrip)
|
|
118
123
|
|
|
119
124
|
| | inproc | ipc | tcp |
|
|
120
125
|
|---|--------|-----|-----|
|
|
121
|
-
| **Async** |
|
|
122
|
-
| **Threads** |
|
|
126
|
+
| **Async** | 60.7 µs | 112.6 µs | 127.8 µs |
|
|
127
|
+
| **Threads** | 74.9 µs | 109.2 µs | 119.6 µs |
|
|
123
128
|
|
|
124
|
-
|
|
129
|
+
See [bench/README.md](bench/README.md) for full results, measurement details, and scripts.
|
|
125
130
|
|
|
126
131
|
## API Reference
|
|
127
132
|
|
data/lib/cztop/curve/auth.rb
CHANGED
|
@@ -29,7 +29,9 @@ module CZTop
|
|
|
29
29
|
@allow_any = allow_any
|
|
30
30
|
@zap = CZTop::Socket::REP.new
|
|
31
31
|
@zap.linger = 0
|
|
32
|
+
@zap.recv_timeout = 0.1
|
|
32
33
|
@zap.bind('inproc://zeromq.zap.01')
|
|
34
|
+
@stopping = false
|
|
33
35
|
@thread = Thread.new { run }
|
|
34
36
|
ObjectSpace.define_finalizer(self, self.class._poststop(@thread))
|
|
35
37
|
end
|
|
@@ -60,8 +62,9 @@ module CZTop
|
|
|
60
62
|
#
|
|
61
63
|
def stop
|
|
62
64
|
ObjectSpace.undefine_finalizer(self)
|
|
63
|
-
@
|
|
64
|
-
@thread.join
|
|
65
|
+
@stopping = true
|
|
66
|
+
@thread.join
|
|
67
|
+
nil
|
|
65
68
|
end
|
|
66
69
|
|
|
67
70
|
# @api private
|
|
@@ -75,8 +78,12 @@ module CZTop
|
|
|
75
78
|
private
|
|
76
79
|
|
|
77
80
|
def run
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
until @stopping
|
|
82
|
+
begin
|
|
83
|
+
msg = @zap.receive
|
|
84
|
+
rescue IO::TimeoutError
|
|
85
|
+
next
|
|
86
|
+
end
|
|
80
87
|
# ZAP request: [version, request_id, domain, address, identity, mechanism, credential]
|
|
81
88
|
version = msg[0]
|
|
82
89
|
request_id = msg[1]
|
|
@@ -90,8 +97,8 @@ module CZTop
|
|
|
90
97
|
|
|
91
98
|
@zap.__send__(:send, [version, request_id, status, '', '', ''])
|
|
92
99
|
end
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
ensure
|
|
101
|
+
@zap.close
|
|
95
102
|
end
|
|
96
103
|
|
|
97
104
|
end
|
data/lib/cztop/curve.rb
CHANGED
|
@@ -6,7 +6,7 @@ module CZTop
|
|
|
6
6
|
#
|
|
7
7
|
# Provides keypair generation, key derivation, and Z85 encoding/decoding.
|
|
8
8
|
# CURVE options are applied to sockets via the +curve:+ keyword argument
|
|
9
|
-
# in socket constructors
|
|
9
|
+
# in socket constructors; there are no public CURVE methods on Socket.
|
|
10
10
|
#
|
|
11
11
|
module CURVE
|
|
12
12
|
|
data/lib/cztop/ffi.rb
CHANGED
|
@@ -6,6 +6,8 @@ module CZMQ
|
|
|
6
6
|
module FFI
|
|
7
7
|
extend ::FFI::Library
|
|
8
8
|
|
|
9
|
+
# Runtime packages may only include versioned sonames. Keep each library's
|
|
10
|
+
# alternatives in one array so FFI can fall back to platform-specific names.
|
|
9
11
|
ffi_lib ['libzmq.so.5', 'libzmq'], ['libczmq.so.4', 'libczmq']
|
|
10
12
|
|
|
11
13
|
# -----------------------------------------------------------------
|
|
@@ -122,6 +124,7 @@ module CZMQ
|
|
|
122
124
|
# -----------------------------------------------------------------
|
|
123
125
|
attach_function :zstr_send, [:pointer, :string], :int, **opts
|
|
124
126
|
attach_function :zstr_sendm, [:pointer, :string], :int, **opts
|
|
127
|
+
attach_function :zstr_free, [:pointer], :void
|
|
125
128
|
|
|
126
129
|
# -----------------------------------------------------------------
|
|
127
130
|
# zsock_wait (used for zactor START synchronization)
|
|
@@ -296,23 +299,23 @@ module CZMQ
|
|
|
296
299
|
|
|
297
300
|
# Instance methods
|
|
298
301
|
def endpoint
|
|
299
|
-
CZMQ::FFI.zsock_endpoint(
|
|
302
|
+
CZMQ::FFI.zsock_endpoint(to_ptr)
|
|
300
303
|
end
|
|
301
304
|
|
|
302
305
|
def connect(format, *args)
|
|
303
|
-
CZMQ::FFI.zsock_connect(
|
|
306
|
+
CZMQ::FFI.zsock_connect(to_ptr, format, *args)
|
|
304
307
|
end
|
|
305
308
|
|
|
306
309
|
def disconnect(format, *args)
|
|
307
|
-
CZMQ::FFI.zsock_disconnect(
|
|
310
|
+
CZMQ::FFI.zsock_disconnect(to_ptr, format, *args)
|
|
308
311
|
end
|
|
309
312
|
|
|
310
313
|
def bind(format, *args)
|
|
311
|
-
CZMQ::FFI.zsock_bind(
|
|
314
|
+
CZMQ::FFI.zsock_bind(to_ptr, format, *args)
|
|
312
315
|
end
|
|
313
316
|
|
|
314
317
|
def unbind(format, *args)
|
|
315
|
-
CZMQ::FFI.zsock_unbind(
|
|
318
|
+
CZMQ::FFI.zsock_unbind(to_ptr, format, *args)
|
|
316
319
|
end
|
|
317
320
|
|
|
318
321
|
def destroy
|
|
@@ -325,11 +328,11 @@ module CZMQ
|
|
|
325
328
|
end
|
|
326
329
|
|
|
327
330
|
def set_subscribe(prefix)
|
|
328
|
-
CZMQ::FFI.zsock_set_subscribe(
|
|
331
|
+
CZMQ::FFI.zsock_set_subscribe(to_ptr, prefix)
|
|
329
332
|
end
|
|
330
333
|
|
|
331
334
|
def set_unsubscribe(prefix)
|
|
332
|
-
CZMQ::FFI.zsock_set_unsubscribe(
|
|
335
|
+
CZMQ::FFI.zsock_set_unsubscribe(to_ptr, prefix)
|
|
333
336
|
end
|
|
334
337
|
|
|
335
338
|
# Class methods that take a zsock pointer (or wrapper with to_ptr)
|
|
@@ -423,9 +426,15 @@ module CZMQ
|
|
|
423
426
|
# Override Object#send: int zmsg_send(zmsg_t **self_p, void *dest)
|
|
424
427
|
# Called as: Zmsg.send(zmsg_wrapper_or_ptr, destination)
|
|
425
428
|
def self.send(msg, dest)
|
|
426
|
-
msg_ptr = msg.respond_to?(:__ptr_give_ref) ? msg.__ptr_give_ref : msg
|
|
427
429
|
dest_ptr = dest.respond_to?(:to_ptr) ? dest.to_ptr : dest
|
|
428
|
-
|
|
430
|
+
msg_ptr = msg.respond_to?(:__ptr_give_ref) ? msg.__ptr_give_ref : msg
|
|
431
|
+
rc = CZMQ::FFI.zmsg_send(msg_ptr, dest_ptr)
|
|
432
|
+
unless rc.zero?
|
|
433
|
+
errno = CZMQ::FFI::Errors.errno
|
|
434
|
+
CZMQ::FFI.zmsg_destroy(msg_ptr) if msg.respond_to?(:__ptr_give_ref)
|
|
435
|
+
CZTop::HasFFIDelegate.raise_zmq_err(errno: errno)
|
|
436
|
+
end
|
|
437
|
+
rc
|
|
429
438
|
end
|
|
430
439
|
|
|
431
440
|
def self.recv(source)
|
|
@@ -437,17 +446,17 @@ module CZMQ
|
|
|
437
446
|
# Appends a Ruby string directly without intermediate MemoryPointer copy.
|
|
438
447
|
# Uses :buffer_in to pass the string's internal buffer pointer to C.
|
|
439
448
|
def add_buffer(str)
|
|
440
|
-
CZMQ::FFI.zmsg_addmem_s(
|
|
449
|
+
CZMQ::FFI.zmsg_addmem_s(to_ptr, str, str.bytesize)
|
|
441
450
|
end
|
|
442
451
|
|
|
443
452
|
def first
|
|
444
|
-
ptr = CZMQ::FFI.zmsg_first(
|
|
453
|
+
ptr = CZMQ::FFI.zmsg_first(to_ptr)
|
|
445
454
|
return nil if ptr.null?
|
|
446
455
|
_borrowed_frame(ptr)
|
|
447
456
|
end
|
|
448
457
|
|
|
449
458
|
def next
|
|
450
|
-
ptr = CZMQ::FFI.zmsg_next(
|
|
459
|
+
ptr = CZMQ::FFI.zmsg_next(to_ptr)
|
|
451
460
|
return nil if ptr.null?
|
|
452
461
|
_borrowed_frame(ptr)
|
|
453
462
|
end
|
|
@@ -461,7 +470,7 @@ module CZMQ
|
|
|
461
470
|
end
|
|
462
471
|
|
|
463
472
|
# -----------------------------------------------------------------
|
|
464
|
-
# Zframe (lightweight
|
|
473
|
+
# Zframe (lightweight; only used for borrowed frames from Zmsg)
|
|
465
474
|
# -----------------------------------------------------------------
|
|
466
475
|
class Zframe
|
|
467
476
|
# Wraps a borrowed zframe_t pointer (not owned, no finalizer).
|
data/lib/cztop/monitor.rb
CHANGED
|
@@ -69,6 +69,7 @@ module CZTop
|
|
|
69
69
|
# @return [Event, nil] the event, or nil on timeout
|
|
70
70
|
#
|
|
71
71
|
def receive(timeout: 0.1)
|
|
72
|
+
raise IOError, 'monitor is closed' if @closed
|
|
72
73
|
CZMQ::FFI.zsock_set_rcvtimeo(@actor_ptr, (timeout * 1000).to_i)
|
|
73
74
|
|
|
74
75
|
zmsg_ptr = CZMQ::FFI.zmsg_recv(@actor_ptr)
|
data/lib/cztop/socket/dealer.rb
CHANGED
|
@@ -13,7 +13,7 @@ module CZTop
|
|
|
13
13
|
|
|
14
14
|
# @param endpoints [String] endpoints to connect to
|
|
15
15
|
# @param curve [Hash, nil] CURVE encryption options
|
|
16
|
-
# @param linger [
|
|
16
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
17
17
|
#
|
|
18
18
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
19
19
|
super
|
data/lib/cztop/socket/pair.rb
CHANGED
|
@@ -13,7 +13,7 @@ module CZTop
|
|
|
13
13
|
|
|
14
14
|
# @param endpoints [String] endpoints to connect to
|
|
15
15
|
# @param curve [Hash, nil] CURVE encryption options
|
|
16
|
-
# @param linger [
|
|
16
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
17
17
|
#
|
|
18
18
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
19
19
|
super
|
data/lib/cztop/socket/pub.rb
CHANGED
|
@@ -12,7 +12,7 @@ module CZTop
|
|
|
12
12
|
|
|
13
13
|
# @param endpoints [String] endpoints to bind to
|
|
14
14
|
# @param curve [Hash, nil] CURVE encryption options
|
|
15
|
-
# @param linger [
|
|
15
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
16
16
|
#
|
|
17
17
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
18
18
|
super
|
data/lib/cztop/socket/pull.rb
CHANGED
|
@@ -12,7 +12,7 @@ module CZTop
|
|
|
12
12
|
|
|
13
13
|
# @param endpoints [String] endpoints to bind to
|
|
14
14
|
# @param curve [Hash, nil] CURVE encryption options
|
|
15
|
-
# @param linger [
|
|
15
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
16
16
|
#
|
|
17
17
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
18
18
|
super
|
data/lib/cztop/socket/push.rb
CHANGED
|
@@ -12,7 +12,7 @@ module CZTop
|
|
|
12
12
|
|
|
13
13
|
# @param endpoints [String] endpoints to connect to
|
|
14
14
|
# @param curve [Hash, nil] CURVE encryption options
|
|
15
|
-
# @param linger [
|
|
15
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
16
16
|
#
|
|
17
17
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
18
18
|
super
|
|
@@ -18,6 +18,7 @@ module CZTop
|
|
|
18
18
|
# Fast path: nonblock recv (no GVL release)
|
|
19
19
|
parts = recv_nonblock
|
|
20
20
|
return parts if parts
|
|
21
|
+
raise IO::EAGAINWaitReadable if read_timeout == 0
|
|
21
22
|
|
|
22
23
|
# Slow path: FD poll → blocking recv
|
|
23
24
|
wait_readable
|
|
@@ -56,7 +57,11 @@ module CZTop
|
|
|
56
57
|
def recv_nonblock
|
|
57
58
|
sock_ptr = to_ptr
|
|
58
59
|
frame = CZMQ::FFI.zframe_recv_nowait(sock_ptr)
|
|
59
|
-
|
|
60
|
+
if frame.null?
|
|
61
|
+
errno = CZMQ::FFI::Errors.errno
|
|
62
|
+
HasFFIDelegate.raise_zmq_err(errno: errno) unless errno == Errno::EAGAIN::Errno
|
|
63
|
+
return nil
|
|
64
|
+
end
|
|
60
65
|
|
|
61
66
|
pp = _zframe_pp
|
|
62
67
|
parts = []
|
data/lib/cztop/socket/rep.rb
CHANGED
|
@@ -13,7 +13,7 @@ module CZTop
|
|
|
13
13
|
|
|
14
14
|
# @param endpoints [String] endpoints to bind to
|
|
15
15
|
# @param curve [Hash, nil] CURVE encryption options
|
|
16
|
-
# @param linger [
|
|
16
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
17
17
|
#
|
|
18
18
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
19
19
|
super
|
data/lib/cztop/socket/req.rb
CHANGED
|
@@ -13,7 +13,7 @@ module CZTop
|
|
|
13
13
|
|
|
14
14
|
# @param endpoints [String] endpoints to connect to
|
|
15
15
|
# @param curve [Hash, nil] CURVE encryption options
|
|
16
|
-
# @param linger [
|
|
16
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
17
17
|
#
|
|
18
18
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
19
19
|
super
|
data/lib/cztop/socket/router.rb
CHANGED
|
@@ -13,7 +13,7 @@ module CZTop
|
|
|
13
13
|
|
|
14
14
|
# @param endpoints [String] endpoints to bind to
|
|
15
15
|
# @param curve [Hash, nil] CURVE encryption options
|
|
16
|
-
# @param linger [
|
|
16
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
17
17
|
#
|
|
18
18
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
19
19
|
super
|
data/lib/cztop/socket/stream.rb
CHANGED
|
@@ -14,7 +14,7 @@ module CZTop
|
|
|
14
14
|
|
|
15
15
|
# @param endpoints [String] endpoints to connect to
|
|
16
16
|
# @param curve [Hash, nil] CURVE encryption options
|
|
17
|
-
# @param linger [
|
|
17
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
18
18
|
#
|
|
19
19
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
20
20
|
super
|
data/lib/cztop/socket/sub.rb
CHANGED
|
@@ -17,7 +17,7 @@ module CZTop
|
|
|
17
17
|
# @param prefix [String, nil] subscription prefix; defaults to no
|
|
18
18
|
# subscription. Pass {EVERYTHING} (+""+) to subscribe to everything.
|
|
19
19
|
# @param curve [Hash, nil] CURVE encryption options
|
|
20
|
-
# @param linger [
|
|
20
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
21
21
|
#
|
|
22
22
|
def initialize(endpoints = nil, prefix: nil, curve: nil, linger: 0)
|
|
23
23
|
super(endpoints, curve: curve, linger: linger)
|
|
@@ -16,18 +16,19 @@ module CZTop
|
|
|
16
16
|
# @return [self]
|
|
17
17
|
#
|
|
18
18
|
def send(message)
|
|
19
|
-
parts = message.is_a?(Array) ? message : [message]
|
|
19
|
+
parts = message.is_a?(Array) ? message.map(&:to_s) : [message.to_s]
|
|
20
20
|
raise ArgumentError, 'message has no parts' if parts.empty?
|
|
21
21
|
|
|
22
22
|
# Fast path: nonblock send (no GVL release)
|
|
23
23
|
return self if send_nonblock(parts)
|
|
24
|
+
raise IO::EAGAINWaitWritable if write_timeout == 0
|
|
24
25
|
|
|
25
26
|
# Slow path: FD poll → blocking send
|
|
26
27
|
wait_writable
|
|
27
28
|
|
|
28
29
|
zmsg = CZMQ::FFI::Zmsg.new
|
|
29
30
|
parts.each do |part|
|
|
30
|
-
rc = zmsg.add_buffer(part
|
|
31
|
+
rc = zmsg.add_buffer(part)
|
|
31
32
|
HasFFIDelegate.raise_zmq_err unless rc.zero?
|
|
32
33
|
end
|
|
33
34
|
|
|
@@ -65,9 +66,8 @@ module CZTop
|
|
|
65
66
|
last_idx = parts.size - 1
|
|
66
67
|
|
|
67
68
|
parts.each_with_index do |part, i|
|
|
68
|
-
|
|
69
|
-
frame
|
|
70
|
-
return false if frame.null?
|
|
69
|
+
frame = CZMQ::FFI.zframe_new_s(part, part.bytesize)
|
|
70
|
+
raise NoMemoryError, 'could not allocate message frame' if frame.null?
|
|
71
71
|
|
|
72
72
|
flags = CZMQ::FFI::ZFRAME_DONTWAIT
|
|
73
73
|
flags |= CZMQ::FFI::ZFRAME_MORE if i < last_idx
|
|
@@ -75,7 +75,9 @@ module CZTop
|
|
|
75
75
|
pp.write_pointer(frame)
|
|
76
76
|
rc = CZMQ::FFI.zframe_send(pp, sock_ptr, flags)
|
|
77
77
|
unless rc.zero?
|
|
78
|
+
errno = CZMQ::FFI::Errors.errno
|
|
78
79
|
CZMQ::FFI.zframe_destroy(pp)
|
|
80
|
+
HasFFIDelegate.raise_zmq_err(errno: errno) unless errno == Errno::EAGAIN::Errno
|
|
79
81
|
return false
|
|
80
82
|
end
|
|
81
83
|
end
|
data/lib/cztop/socket/xpub.rb
CHANGED
|
@@ -13,7 +13,7 @@ module CZTop
|
|
|
13
13
|
|
|
14
14
|
# @param endpoints [String] endpoints to bind to
|
|
15
15
|
# @param curve [Hash, nil] CURVE encryption options
|
|
16
|
-
# @param linger [
|
|
16
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
17
17
|
#
|
|
18
18
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
19
19
|
super
|
data/lib/cztop/socket/xsub.rb
CHANGED
|
@@ -13,7 +13,7 @@ module CZTop
|
|
|
13
13
|
|
|
14
14
|
# @param endpoints [String] endpoints to connect to
|
|
15
15
|
# @param curve [Hash, nil] CURVE encryption options
|
|
16
|
-
# @param linger [
|
|
16
|
+
# @param linger [Numeric, nil] linger period in seconds (default: 0)
|
|
17
17
|
#
|
|
18
18
|
def initialize(endpoints = nil, curve: nil, linger: 0)
|
|
19
19
|
super
|
data/lib/cztop/socket.rb
CHANGED
|
@@ -142,7 +142,7 @@ module CZTop
|
|
|
142
142
|
# Connects or binds based on CZMQ endpoint prefix convention.
|
|
143
143
|
# @api private
|
|
144
144
|
# @param endpoints [String] endpoint, optionally prefixed with +@+ (bind) or +>+ (connect)
|
|
145
|
-
# @param default [Symbol] +:connect+ or +:bind
|
|
145
|
+
# @param default [Symbol] +:connect+ or +:bind+; action when no prefix given
|
|
146
146
|
#
|
|
147
147
|
def _attach(endpoints, default:)
|
|
148
148
|
return unless endpoints
|
data/lib/cztop/version.rb
CHANGED
data/lib/cztop/zsock_options.rb
CHANGED
|
@@ -145,7 +145,15 @@ module CZTop
|
|
|
145
145
|
# @return [String] current socket identity
|
|
146
146
|
#
|
|
147
147
|
def identity
|
|
148
|
-
Zsock.identity(self)
|
|
148
|
+
ptr = Zsock.identity(self)
|
|
149
|
+
HasFFIDelegate.raise_zmq_err if ptr.null?
|
|
150
|
+
begin
|
|
151
|
+
ptr.read_string
|
|
152
|
+
ensure
|
|
153
|
+
ref = ::FFI::MemoryPointer.new(:pointer)
|
|
154
|
+
ref.write_pointer(ptr)
|
|
155
|
+
CZMQ::FFI.zstr_free(ref)
|
|
156
|
+
end
|
|
149
157
|
end
|
|
150
158
|
|
|
151
159
|
|
data/lib/cztop.rb
CHANGED
|
@@ -40,5 +40,5 @@ require_relative 'cztop/monitor'
|
|
|
40
40
|
require_relative 'cztop/curve'
|
|
41
41
|
require_relative 'cztop/curve/auth'
|
|
42
42
|
|
|
43
|
-
# Convenience alias
|
|
43
|
+
# Convenience alias; allows `Cztop::Socket::REQ` alongside `CZTop::Socket::REQ`.
|
|
44
44
|
Cztop = CZTop
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cztop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -198,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
198
198
|
- !ruby/object:Gem::Version
|
|
199
199
|
version: '0'
|
|
200
200
|
requirements: []
|
|
201
|
-
rubygems_version: 4.0.
|
|
201
|
+
rubygems_version: 4.0.20
|
|
202
202
|
specification_version: 4
|
|
203
203
|
summary: CZMQ FFI binding to bring ZMQ sockets to Ruby
|
|
204
204
|
test_files: []
|