omq 0.4.1 → 0.4.2
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/CHANGELOG.md +25 -1
- data/README.md +1 -1
- data/lib/omq/push_pull.rb +4 -4
- data/lib/omq/socket.rb +6 -1
- data/lib/omq/version.rb +1 -1
- data/lib/omq/zmtp/connection.rb +1 -1
- data/lib/omq/zmtp/engine.rb +2 -2
- data/lib/omq/zmtp/mechanism/null.rb +2 -0
- data/lib/omq/zmtp/routing/round_robin.rb +9 -4
- data/lib/omq/zmtp/transport/inproc.rb +19 -2
- 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: 0dc74658712882f8d0eb8f58b0c9a37c959d50c87116677d23be39904f7002e7
|
|
4
|
+
data.tar.gz: 1ba17796cac6b1cd594ebbee874428e0675153d461d168e0f69f07abab608ef8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3628a755a53010690ae407ac790eb83ef7592ac5cac34bddff8a62782c20cb6092c3dd300ae71a2dfff324eaf8457ba319305b6892ca259f8990ce63267c74e0
|
|
7
|
+
data.tar.gz: 76502cad1a484cf8224285fbf4259e9ba8e5daa396caa42ac3716b50ada2e72a4c31b8d256208ab7410f5e48727216fee526efbf6166e3a1a32bb7bc1701cacb
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.2 — 2026-03-27
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Send pump dies permanently on connection loss — `rescue` was outside
|
|
8
|
+
the loop, so a single `CONNECTION_LOST` killed the pump and all
|
|
9
|
+
subsequent messages queued but never sent
|
|
10
|
+
- NULL handshake deadlocks with buffered IO — missing `io.flush` after
|
|
11
|
+
greeting and READY writes caused both peers to block on read
|
|
12
|
+
- Inproc DirectPipe drops messages when send pump runs before
|
|
13
|
+
`direct_recv_queue` is wired — now buffers to `@pending_direct` and
|
|
14
|
+
drains on assignment
|
|
15
|
+
- HWM and timeout options set after construction had no effect because
|
|
16
|
+
`Async::LimitedQueue` was already allocated with the default
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- `send_hwm:`, `send_timeout:` constructor kwargs for `PUSH`
|
|
21
|
+
- `recv_hwm:`, `recv_timeout:` constructor kwargs for `PULL`
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Use `Async::Clock.now` instead of `Process.clock_gettime` internally
|
|
26
|
+
|
|
3
27
|
## 0.4.1 — 2026-03-27
|
|
4
28
|
|
|
5
29
|
### Improved
|
|
@@ -137,4 +161,4 @@ Initial release. Pure Ruby implementation of ZMTP 3.1 (ZeroMQ) using Async.
|
|
|
137
161
|
- Linger on close (drain send queue before closing)
|
|
138
162
|
- `max_message_size` enforcement
|
|
139
163
|
- Works inside Async reactors or standalone (shared IO thread)
|
|
140
|
-
- Optional CURVE encryption via the [omq-curve](https://github.com/
|
|
164
|
+
- Optional CURVE encryption via the [omq-curve](https://github.com/zeromq/omq-curve) gem
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# OMQ! Where did the C dependency go?!
|
|
2
2
|
|
|
3
|
-
[](https://github.com/zeromq/omq/actions/workflows/ci.yml)
|
|
4
4
|
[](https://rubygems.org/gems/omq)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://www.ruby-lang.org)
|
data/lib/omq/push_pull.rb
CHANGED
|
@@ -4,8 +4,8 @@ module OMQ
|
|
|
4
4
|
class PUSH < Socket
|
|
5
5
|
include ZMTP::Writable
|
|
6
6
|
|
|
7
|
-
def initialize(endpoints = nil, linger: 0)
|
|
8
|
-
_init_engine(:PUSH, linger: linger)
|
|
7
|
+
def initialize(endpoints = nil, linger: 0, send_hwm: nil, send_timeout: nil)
|
|
8
|
+
_init_engine(:PUSH, linger: linger, send_hwm: send_hwm, send_timeout: send_timeout)
|
|
9
9
|
_attach(endpoints, default: :connect)
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -13,8 +13,8 @@ module OMQ
|
|
|
13
13
|
class PULL < Socket
|
|
14
14
|
include ZMTP::Readable
|
|
15
15
|
|
|
16
|
-
def initialize(endpoints = nil, linger: 0)
|
|
17
|
-
_init_engine(:PULL, linger: linger)
|
|
16
|
+
def initialize(endpoints = nil, linger: 0, recv_hwm: nil, recv_timeout: nil)
|
|
17
|
+
_init_engine(:PULL, linger: linger, recv_hwm: recv_hwm, recv_timeout: recv_timeout)
|
|
18
18
|
_attach(endpoints, default: :bind)
|
|
19
19
|
end
|
|
20
20
|
end
|
data/lib/omq/socket.rb
CHANGED
|
@@ -164,8 +164,13 @@ module OMQ
|
|
|
164
164
|
# @param socket_type [Symbol]
|
|
165
165
|
# @param linger [Integer]
|
|
166
166
|
#
|
|
167
|
-
def _init_engine(socket_type, linger:
|
|
167
|
+
def _init_engine(socket_type, linger:, send_hwm: nil, recv_hwm: nil,
|
|
168
|
+
send_timeout: nil, recv_timeout: nil)
|
|
168
169
|
@options = ZMTP::Options.new(linger: linger)
|
|
170
|
+
@options.send_hwm = send_hwm if send_hwm
|
|
171
|
+
@options.recv_hwm = recv_hwm if recv_hwm
|
|
172
|
+
@options.send_timeout = send_timeout if send_timeout
|
|
173
|
+
@options.recv_timeout = recv_timeout if recv_timeout
|
|
169
174
|
@engine = ZMTP::Engine.new(socket_type, @options)
|
|
170
175
|
end
|
|
171
176
|
end
|
data/lib/omq/version.rb
CHANGED
data/lib/omq/zmtp/connection.rb
CHANGED
data/lib/omq/zmtp/engine.rb
CHANGED
|
@@ -243,11 +243,11 @@ module OMQ
|
|
|
243
243
|
#
|
|
244
244
|
def drain_send_queues(timeout)
|
|
245
245
|
return unless @routing.respond_to?(:send_queue)
|
|
246
|
-
deadline = timeout ?
|
|
246
|
+
deadline = timeout ? Async::Clock.now + timeout : nil
|
|
247
247
|
|
|
248
248
|
until @routing.send_queue.empty?
|
|
249
249
|
if deadline
|
|
250
|
-
remaining = deadline -
|
|
250
|
+
remaining = deadline - Async::Clock.now
|
|
251
251
|
break if remaining <= 0
|
|
252
252
|
end
|
|
253
253
|
sleep 0.001
|
|
@@ -26,6 +26,7 @@ module OMQ
|
|
|
26
26
|
def handshake!(io, as_server:, socket_type:, identity:)
|
|
27
27
|
# Send our greeting
|
|
28
28
|
io.write(Codec::Greeting.encode(mechanism: MECHANISM_NAME, as_server: as_server))
|
|
29
|
+
io.flush
|
|
29
30
|
|
|
30
31
|
# Read peer greeting
|
|
31
32
|
greeting_data = io.read_exactly(Codec::Greeting::SIZE)
|
|
@@ -38,6 +39,7 @@ module OMQ
|
|
|
38
39
|
# Send our READY command
|
|
39
40
|
ready_cmd = Codec::Command.ready(socket_type: socket_type, identity: identity)
|
|
40
41
|
io.write(ready_cmd.to_frame.to_wire)
|
|
42
|
+
io.flush
|
|
41
43
|
|
|
42
44
|
# Read peer READY command
|
|
43
45
|
frame = Codec::Frame.read_from(io)
|
|
@@ -56,13 +56,18 @@ module OMQ
|
|
|
56
56
|
@tasks << Reactor.spawn_pump do
|
|
57
57
|
loop do
|
|
58
58
|
parts = @send_queue.dequeue
|
|
59
|
-
|
|
60
|
-
conn.send_message(transform_send(parts))
|
|
59
|
+
send_with_retry(parts)
|
|
61
60
|
end
|
|
62
|
-
rescue *ZMTP::CONNECTION_LOST
|
|
63
|
-
# connection lost mid-write
|
|
64
61
|
end
|
|
65
62
|
end
|
|
63
|
+
|
|
64
|
+
def send_with_retry(parts)
|
|
65
|
+
conn = next_connection
|
|
66
|
+
conn.send_message(transform_send(parts))
|
|
67
|
+
rescue *ZMTP::CONNECTION_LOST
|
|
68
|
+
@engine.connection_lost(conn)
|
|
69
|
+
retry
|
|
70
|
+
end
|
|
66
71
|
end
|
|
67
72
|
end
|
|
68
73
|
end
|
|
@@ -202,7 +202,7 @@ module OMQ
|
|
|
202
202
|
# @return [Async::LimitedQueue, nil] when set, {#send_message}
|
|
203
203
|
# enqueues directly here instead of using the internal queue
|
|
204
204
|
#
|
|
205
|
-
|
|
205
|
+
attr_reader :direct_recv_queue
|
|
206
206
|
|
|
207
207
|
# @return [Proc, nil] optional transform applied before
|
|
208
208
|
# enqueuing into {#direct_recv_queue}
|
|
@@ -224,6 +224,20 @@ module OMQ
|
|
|
224
224
|
@peer = nil
|
|
225
225
|
@direct_recv_queue = nil
|
|
226
226
|
@direct_recv_transform = nil
|
|
227
|
+
@pending_direct = nil
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Sets the direct recv queue. Drains any messages that were
|
|
231
|
+
# buffered before the queue was available.
|
|
232
|
+
#
|
|
233
|
+
def direct_recv_queue=(queue)
|
|
234
|
+
@direct_recv_queue = queue
|
|
235
|
+
if queue && @pending_direct
|
|
236
|
+
@pending_direct.each do |msg|
|
|
237
|
+
queue.enqueue(msg)
|
|
238
|
+
end
|
|
239
|
+
@pending_direct = nil
|
|
240
|
+
end
|
|
227
241
|
end
|
|
228
242
|
|
|
229
243
|
# Sends a multi-frame message.
|
|
@@ -240,8 +254,11 @@ module OMQ
|
|
|
240
254
|
if @direct_recv_queue
|
|
241
255
|
msg = @direct_recv_transform ? @direct_recv_transform.call(parts) : parts
|
|
242
256
|
@direct_recv_queue.enqueue(msg)
|
|
243
|
-
|
|
257
|
+
elsif @send_queue
|
|
244
258
|
@send_queue.enqueue(parts)
|
|
259
|
+
else
|
|
260
|
+
msg = @direct_recv_transform ? @direct_recv_transform.call(parts) : parts
|
|
261
|
+
(@pending_direct ||= []) << msg
|
|
245
262
|
end
|
|
246
263
|
end
|
|
247
264
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omq
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -88,7 +88,7 @@ files:
|
|
|
88
88
|
- lib/omq/zmtp/transport/tcp.rb
|
|
89
89
|
- lib/omq/zmtp/valid_peers.rb
|
|
90
90
|
- lib/omq/zmtp/writable.rb
|
|
91
|
-
homepage: https://github.com/
|
|
91
|
+
homepage: https://github.com/zeromq/omq
|
|
92
92
|
licenses:
|
|
93
93
|
- ISC
|
|
94
94
|
metadata: {}
|