omq 0.13.0 → 0.14.1
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 +44 -0
- data/README.md +27 -0
- data/lib/omq/drop_queue.rb +3 -0
- data/lib/omq/engine/connection_setup.rb +38 -15
- data/lib/omq/engine/heartbeat.rb +1 -1
- data/lib/omq/engine/maintenance.rb +35 -0
- data/lib/omq/engine/reconnect.rb +38 -12
- data/lib/omq/engine/recv_pump.rb +89 -46
- data/lib/omq/engine.rb +44 -2
- data/lib/omq/options.rb +44 -0
- data/lib/omq/pair.rb +6 -0
- data/lib/omq/pub_sub.rb +25 -0
- data/lib/omq/push_pull.rb +17 -0
- data/lib/omq/queue_interface.rb +1 -0
- data/lib/omq/readable.rb +2 -0
- data/lib/omq/req_rep.rb +13 -0
- data/lib/omq/router_dealer.rb +12 -0
- data/lib/omq/routing/conn_send_pump.rb +1 -1
- data/lib/omq/routing/dealer.rb +7 -0
- data/lib/omq/routing/fair_queue.rb +28 -0
- data/lib/omq/routing/fan_out.rb +19 -7
- data/lib/omq/routing/pair.rb +9 -1
- data/lib/omq/routing/pub.rb +8 -0
- data/lib/omq/routing/pull.rb +7 -0
- data/lib/omq/routing/rep.rb +11 -1
- data/lib/omq/routing/req.rb +7 -0
- data/lib/omq/routing/round_robin.rb +4 -3
- data/lib/omq/routing/router.rb +10 -1
- data/lib/omq/routing/sub.rb +10 -0
- data/lib/omq/routing/xpub.rb +8 -0
- data/lib/omq/routing/xsub.rb +13 -3
- data/lib/omq/routing.rb +26 -11
- data/lib/omq/socket.rb +23 -5
- data/lib/omq/transport/inproc/direct_pipe.rb +12 -1
- data/lib/omq/transport/inproc.rb +5 -0
- data/lib/omq/transport/ipc.rb +7 -1
- data/lib/omq/transport/tcp.rb +12 -7
- data/lib/omq/version.rb +1 -1
- data/lib/omq/writable.rb +2 -0
- data/lib/omq.rb +4 -1
- metadata +6 -5
data/lib/omq/routing/rep.rb
CHANGED
|
@@ -13,6 +13,7 @@ module OMQ
|
|
|
13
13
|
|
|
14
14
|
EMPTY_FRAME = "".b.freeze
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
# @param engine [Engine]
|
|
17
18
|
#
|
|
18
19
|
def initialize(engine)
|
|
@@ -24,6 +25,7 @@ module OMQ
|
|
|
24
25
|
@tasks = []
|
|
25
26
|
end
|
|
26
27
|
|
|
28
|
+
|
|
27
29
|
# @return [FairQueue]
|
|
28
30
|
#
|
|
29
31
|
attr_reader :recv_queue
|
|
@@ -44,6 +46,7 @@ module OMQ
|
|
|
44
46
|
@conn_send_tasks[connection] = ConnSendPump.start(@engine, connection, q, @tasks)
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
|
|
47
50
|
# @param connection [Connection]
|
|
48
51
|
#
|
|
49
52
|
def connection_removed(connection)
|
|
@@ -53,6 +56,7 @@ module OMQ
|
|
|
53
56
|
@conn_send_tasks.delete(connection)&.stop
|
|
54
57
|
end
|
|
55
58
|
|
|
59
|
+
|
|
56
60
|
# Enqueues a reply. Routes to the connection that sent the matching
|
|
57
61
|
# request by consuming the next pending_reply entry.
|
|
58
62
|
#
|
|
@@ -65,12 +69,18 @@ module OMQ
|
|
|
65
69
|
@conn_queues[conn]&.enqueue([*reply_info[:envelope], EMPTY_FRAME, *parts])
|
|
66
70
|
end
|
|
67
71
|
|
|
72
|
+
|
|
73
|
+
# Stops all background tasks.
|
|
74
|
+
#
|
|
75
|
+
# @return [void]
|
|
76
|
+
#
|
|
68
77
|
def stop
|
|
69
78
|
@tasks.each(&:stop)
|
|
70
79
|
@tasks.clear
|
|
71
80
|
end
|
|
72
81
|
|
|
73
|
-
|
|
82
|
+
|
|
83
|
+
# @return [Boolean] true when all per-connection send queues are empty
|
|
74
84
|
#
|
|
75
85
|
def send_queues_drained?
|
|
76
86
|
@conn_queues.values.all?(&:empty?)
|
data/lib/omq/routing/req.rb
CHANGED
|
@@ -20,6 +20,7 @@ module OMQ
|
|
|
20
20
|
init_round_robin(engine)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
|
|
23
24
|
# @return [FairQueue]
|
|
24
25
|
#
|
|
25
26
|
attr_reader :recv_queue
|
|
@@ -36,6 +37,7 @@ module OMQ
|
|
|
36
37
|
add_round_robin_send_connection(connection)
|
|
37
38
|
end
|
|
38
39
|
|
|
40
|
+
|
|
39
41
|
# @param connection [Connection]
|
|
40
42
|
#
|
|
41
43
|
def connection_removed(connection)
|
|
@@ -44,6 +46,7 @@ module OMQ
|
|
|
44
46
|
remove_round_robin_send_connection(connection)
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
|
|
47
50
|
# @param parts [Array<String>]
|
|
48
51
|
#
|
|
49
52
|
def enqueue(parts)
|
|
@@ -52,6 +55,10 @@ module OMQ
|
|
|
52
55
|
enqueue_round_robin(parts)
|
|
53
56
|
end
|
|
54
57
|
|
|
58
|
+
|
|
59
|
+
# Stops all background tasks.
|
|
60
|
+
#
|
|
61
|
+
# @return [void]
|
|
55
62
|
#
|
|
56
63
|
def stop
|
|
57
64
|
@tasks.each(&:stop)
|
|
@@ -15,8 +15,8 @@ module OMQ
|
|
|
15
15
|
# their #initialize.
|
|
16
16
|
#
|
|
17
17
|
module RoundRobin
|
|
18
|
-
#
|
|
19
|
-
# are empty
|
|
18
|
+
# @return [Boolean] true when the staging queue and all per-connection
|
|
19
|
+
# send queues are empty
|
|
20
20
|
#
|
|
21
21
|
def send_queues_drained?
|
|
22
22
|
@staging_queue.empty? && @conn_queues.values.all?(&:empty?)
|
|
@@ -103,7 +103,7 @@ module OMQ
|
|
|
103
103
|
@staging_queue.enqueue(parts)
|
|
104
104
|
else
|
|
105
105
|
conn = next_connection
|
|
106
|
-
@conn_queues[conn]
|
|
106
|
+
@conn_queues[conn].enqueue(parts)
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
109
|
|
|
@@ -165,6 +165,7 @@ module OMQ
|
|
|
165
165
|
@tasks << task
|
|
166
166
|
end
|
|
167
167
|
|
|
168
|
+
|
|
168
169
|
def write_batch(conn, batch)
|
|
169
170
|
if batch.size == 1
|
|
170
171
|
conn.send_message(transform_send(batch[0]))
|
data/lib/omq/routing/router.rb
CHANGED
|
@@ -24,6 +24,7 @@ module OMQ
|
|
|
24
24
|
@tasks = []
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
|
|
27
28
|
# @return [FairQueue]
|
|
28
29
|
#
|
|
29
30
|
attr_reader :recv_queue
|
|
@@ -43,6 +44,7 @@ module OMQ
|
|
|
43
44
|
@conn_send_tasks[connection] = ConnSendPump.start(@engine, connection, q, @tasks)
|
|
44
45
|
end
|
|
45
46
|
|
|
47
|
+
|
|
46
48
|
# @param connection [Connection]
|
|
47
49
|
#
|
|
48
50
|
def connection_removed(connection)
|
|
@@ -53,6 +55,7 @@ module OMQ
|
|
|
53
55
|
@conn_send_tasks.delete(connection)&.stop
|
|
54
56
|
end
|
|
55
57
|
|
|
58
|
+
|
|
56
59
|
# Enqueues a message for sending. The first frame is the routing identity.
|
|
57
60
|
#
|
|
58
61
|
# @param parts [Array<String>]
|
|
@@ -69,12 +72,18 @@ module OMQ
|
|
|
69
72
|
@conn_queues[conn]&.enqueue(parts[1..])
|
|
70
73
|
end
|
|
71
74
|
|
|
75
|
+
|
|
76
|
+
# Stops all background tasks.
|
|
77
|
+
#
|
|
78
|
+
# @return [void]
|
|
79
|
+
#
|
|
72
80
|
def stop
|
|
73
81
|
@tasks.each(&:stop)
|
|
74
82
|
@tasks.clear
|
|
75
83
|
end
|
|
76
84
|
|
|
77
|
-
|
|
85
|
+
|
|
86
|
+
# @return [Boolean] true when all per-connection send queues are empty
|
|
78
87
|
#
|
|
79
88
|
def send_queues_drained?
|
|
80
89
|
@conn_queues.values.all?(&:empty?)
|
data/lib/omq/routing/sub.rb
CHANGED
|
@@ -18,6 +18,7 @@ module OMQ
|
|
|
18
18
|
@tasks = []
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
|
|
21
22
|
# @return [FairQueue]
|
|
22
23
|
#
|
|
23
24
|
attr_reader :recv_queue
|
|
@@ -36,6 +37,7 @@ module OMQ
|
|
|
36
37
|
@tasks << task if task
|
|
37
38
|
end
|
|
38
39
|
|
|
40
|
+
|
|
39
41
|
# @param connection [Connection]
|
|
40
42
|
#
|
|
41
43
|
def connection_removed(connection)
|
|
@@ -43,12 +45,14 @@ module OMQ
|
|
|
43
45
|
@recv_queue.remove_queue(connection)
|
|
44
46
|
end
|
|
45
47
|
|
|
48
|
+
|
|
46
49
|
# SUB is read-only.
|
|
47
50
|
#
|
|
48
51
|
def enqueue(_parts)
|
|
49
52
|
raise "SUB sockets cannot send"
|
|
50
53
|
end
|
|
51
54
|
|
|
55
|
+
|
|
52
56
|
# Subscribes to a topic prefix.
|
|
53
57
|
#
|
|
54
58
|
# @param prefix [String]
|
|
@@ -60,6 +64,7 @@ module OMQ
|
|
|
60
64
|
end
|
|
61
65
|
end
|
|
62
66
|
|
|
67
|
+
|
|
63
68
|
# Unsubscribes from a topic prefix.
|
|
64
69
|
#
|
|
65
70
|
# @param prefix [String]
|
|
@@ -71,6 +76,11 @@ module OMQ
|
|
|
71
76
|
end
|
|
72
77
|
end
|
|
73
78
|
|
|
79
|
+
|
|
80
|
+
# Stops all background tasks.
|
|
81
|
+
#
|
|
82
|
+
# @return [void]
|
|
83
|
+
#
|
|
74
84
|
def stop
|
|
75
85
|
@tasks.each(&:stop)
|
|
76
86
|
@tasks.clear
|
data/lib/omq/routing/xpub.rb
CHANGED
|
@@ -23,6 +23,7 @@ module OMQ
|
|
|
23
23
|
init_fan_out(engine)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
|
|
26
27
|
# @return [Async::LimitedQueue]
|
|
27
28
|
#
|
|
28
29
|
attr_reader :recv_queue
|
|
@@ -36,6 +37,7 @@ module OMQ
|
|
|
36
37
|
add_fan_out_send_connection(connection)
|
|
37
38
|
end
|
|
38
39
|
|
|
40
|
+
|
|
39
41
|
# @param connection [Connection]
|
|
40
42
|
#
|
|
41
43
|
def connection_removed(connection)
|
|
@@ -44,12 +46,17 @@ module OMQ
|
|
|
44
46
|
remove_fan_out_send_connection(connection)
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
|
|
47
50
|
# @param parts [Array<String>]
|
|
48
51
|
#
|
|
49
52
|
def enqueue(parts)
|
|
50
53
|
fan_out_enqueue(parts)
|
|
51
54
|
end
|
|
52
55
|
|
|
56
|
+
|
|
57
|
+
# Stops all background tasks.
|
|
58
|
+
#
|
|
59
|
+
# @return [void]
|
|
53
60
|
#
|
|
54
61
|
def stop
|
|
55
62
|
@tasks.each(&:stop)
|
|
@@ -65,6 +72,7 @@ module OMQ
|
|
|
65
72
|
@recv_queue.enqueue(["\x01#{prefix}".b])
|
|
66
73
|
end
|
|
67
74
|
|
|
75
|
+
|
|
68
76
|
# Expose unsubscription to application as data message.
|
|
69
77
|
#
|
|
70
78
|
def on_cancel(conn, prefix)
|
data/lib/omq/routing/xsub.rb
CHANGED
|
@@ -21,6 +21,7 @@ module OMQ
|
|
|
21
21
|
@tasks = []
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
|
|
24
25
|
# @return [FairQueue]
|
|
25
26
|
#
|
|
26
27
|
attr_reader :recv_queue
|
|
@@ -41,6 +42,7 @@ module OMQ
|
|
|
41
42
|
start_conn_send_pump(connection, q)
|
|
42
43
|
end
|
|
43
44
|
|
|
45
|
+
|
|
44
46
|
# @param connection [Connection]
|
|
45
47
|
#
|
|
46
48
|
def connection_removed(connection)
|
|
@@ -50,6 +52,7 @@ module OMQ
|
|
|
50
52
|
@conn_send_tasks.delete(connection)&.stop
|
|
51
53
|
end
|
|
52
54
|
|
|
55
|
+
|
|
53
56
|
# Enqueues a subscription command (fan-out to all connected PUBs).
|
|
54
57
|
#
|
|
55
58
|
# @param parts [Array<String>]
|
|
@@ -58,13 +61,18 @@ module OMQ
|
|
|
58
61
|
@connections.each { |conn| @conn_queues[conn]&.enqueue(parts) }
|
|
59
62
|
end
|
|
60
63
|
|
|
64
|
+
|
|
65
|
+
# Stops all background tasks.
|
|
66
|
+
#
|
|
67
|
+
# @return [void]
|
|
61
68
|
#
|
|
62
69
|
def stop
|
|
63
70
|
@tasks.each(&:stop)
|
|
64
71
|
@tasks.clear
|
|
65
72
|
end
|
|
66
73
|
|
|
67
|
-
|
|
74
|
+
|
|
75
|
+
# @return [Boolean] true when all per-connection send queues are empty
|
|
68
76
|
#
|
|
69
77
|
def send_queues_drained?
|
|
70
78
|
@conn_queues.values.all?(&:empty?)
|
|
@@ -82,8 +90,10 @@ module OMQ
|
|
|
82
90
|
prefix = frame.byteslice(1..) || "".b
|
|
83
91
|
begin
|
|
84
92
|
case flag
|
|
85
|
-
when 0x01
|
|
86
|
-
|
|
93
|
+
when 0x01
|
|
94
|
+
conn.send_command(Protocol::ZMTP::Codec::Command.subscribe(prefix))
|
|
95
|
+
when 0x00
|
|
96
|
+
conn.send_command(Protocol::ZMTP::Codec::Command.cancel(prefix))
|
|
87
97
|
end
|
|
88
98
|
rescue Protocol::ZMTP::Error, *CONNECTION_LOST
|
|
89
99
|
@engine.connection_lost(conn)
|
data/lib/omq/routing.rb
CHANGED
|
@@ -18,6 +18,7 @@ module OMQ
|
|
|
18
18
|
# Shared frozen empty binary string to avoid repeated allocations.
|
|
19
19
|
EMPTY_BINARY = "".b.freeze
|
|
20
20
|
|
|
21
|
+
|
|
21
22
|
# Plugin registry for socket types not built into omq.
|
|
22
23
|
# Populated by sister gems via +Routing.register+.
|
|
23
24
|
#
|
|
@@ -35,6 +36,7 @@ module OMQ
|
|
|
35
36
|
end
|
|
36
37
|
end
|
|
37
38
|
|
|
39
|
+
|
|
38
40
|
# Builds a send or recv queue based on the mute strategy.
|
|
39
41
|
#
|
|
40
42
|
# @param hwm [Integer] high water mark
|
|
@@ -54,6 +56,7 @@ module OMQ
|
|
|
54
56
|
end
|
|
55
57
|
end
|
|
56
58
|
|
|
59
|
+
|
|
57
60
|
# Drains all available messages from +queue+ into +batch+ without
|
|
58
61
|
# blocking. Call after the initial blocking dequeue.
|
|
59
62
|
#
|
|
@@ -73,6 +76,7 @@ module OMQ
|
|
|
73
76
|
end
|
|
74
77
|
end
|
|
75
78
|
|
|
79
|
+
|
|
76
80
|
# Returns the routing strategy class for a socket type.
|
|
77
81
|
#
|
|
78
82
|
# @param socket_type [Symbol] e.g. :PAIR, :REQ
|
|
@@ -80,17 +84,28 @@ module OMQ
|
|
|
80
84
|
#
|
|
81
85
|
def self.for(socket_type)
|
|
82
86
|
case socket_type
|
|
83
|
-
when :PAIR
|
|
84
|
-
|
|
85
|
-
when :
|
|
86
|
-
|
|
87
|
-
when :
|
|
88
|
-
|
|
89
|
-
when :
|
|
90
|
-
|
|
91
|
-
when :
|
|
92
|
-
|
|
93
|
-
when :
|
|
87
|
+
when :PAIR
|
|
88
|
+
Pair
|
|
89
|
+
when :REQ
|
|
90
|
+
Req
|
|
91
|
+
when :REP
|
|
92
|
+
Rep
|
|
93
|
+
when :DEALER
|
|
94
|
+
Dealer
|
|
95
|
+
when :ROUTER
|
|
96
|
+
Router
|
|
97
|
+
when :PUB
|
|
98
|
+
Pub
|
|
99
|
+
when :SUB
|
|
100
|
+
Sub
|
|
101
|
+
when :XPUB
|
|
102
|
+
XPub
|
|
103
|
+
when :XSUB
|
|
104
|
+
XSub
|
|
105
|
+
when :PUSH
|
|
106
|
+
Push
|
|
107
|
+
when :PULL
|
|
108
|
+
Pull
|
|
94
109
|
else
|
|
95
110
|
@registry[socket_type] or raise ArgumentError, "unknown socket type: #{socket_type.inspect}"
|
|
96
111
|
end
|
data/lib/omq/socket.rb
CHANGED
|
@@ -62,7 +62,12 @@ module OMQ
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
# @param endpoints [String, nil] optional endpoint with prefix convention
|
|
66
|
+
# (+@+ for bind, +>+ for connect, plain uses subclass default)
|
|
67
|
+
# @param linger [Integer] linger period in seconds (default 0)
|
|
68
|
+
#
|
|
69
|
+
def initialize(endpoints = nil, linger: 0)
|
|
70
|
+
end
|
|
66
71
|
|
|
67
72
|
|
|
68
73
|
# Binds to an endpoint.
|
|
@@ -136,6 +141,8 @@ module OMQ
|
|
|
136
141
|
# Signals end-of-stream on the receive side. A subsequent
|
|
137
142
|
# +#receive+ call that would otherwise block returns +nil+.
|
|
138
143
|
#
|
|
144
|
+
# @return [void]
|
|
145
|
+
#
|
|
139
146
|
def close_read
|
|
140
147
|
@engine.dequeue_recv_sentinel
|
|
141
148
|
end
|
|
@@ -182,12 +189,18 @@ module OMQ
|
|
|
182
189
|
|
|
183
190
|
|
|
184
191
|
# Disable auto-reconnect for connected endpoints.
|
|
192
|
+
#
|
|
193
|
+
# @param val [Boolean]
|
|
194
|
+
# @return [void]
|
|
195
|
+
#
|
|
185
196
|
def reconnect_enabled=(val)
|
|
186
197
|
@engine.reconnect_enabled = val
|
|
187
198
|
end
|
|
188
199
|
|
|
189
200
|
|
|
190
|
-
# Closes the socket.
|
|
201
|
+
# Closes the socket and releases all resources.
|
|
202
|
+
#
|
|
203
|
+
# @return [nil]
|
|
191
204
|
#
|
|
192
205
|
def close
|
|
193
206
|
Reactor.run { @engine.close }
|
|
@@ -197,6 +210,8 @@ module OMQ
|
|
|
197
210
|
|
|
198
211
|
# Set socket to use unbounded pipes (HWM=0).
|
|
199
212
|
#
|
|
213
|
+
# @return [nil]
|
|
214
|
+
#
|
|
200
215
|
def set_unbounded
|
|
201
216
|
@options.send_hwm = 0
|
|
202
217
|
@options.recv_hwm = 0
|
|
@@ -277,9 +292,12 @@ module OMQ
|
|
|
277
292
|
@recv_buffer = []
|
|
278
293
|
@recv_mutex = Mutex.new
|
|
279
294
|
@engine = case backend
|
|
280
|
-
when nil, :ruby
|
|
281
|
-
|
|
282
|
-
|
|
295
|
+
when nil, :ruby
|
|
296
|
+
Engine.new(socket_type, @options)
|
|
297
|
+
when :ffi
|
|
298
|
+
FFI::Engine.new(socket_type, @options)
|
|
299
|
+
else
|
|
300
|
+
raise ArgumentError, "unknown backend: #{backend}"
|
|
283
301
|
end
|
|
284
302
|
end
|
|
285
303
|
end
|
|
@@ -64,6 +64,9 @@ module OMQ
|
|
|
64
64
|
# Sets the direct recv queue. Drains any messages that were
|
|
65
65
|
# buffered before the queue was available.
|
|
66
66
|
#
|
|
67
|
+
# @param queue [Async::LimitedQueue, nil]
|
|
68
|
+
# @return [void]
|
|
69
|
+
#
|
|
67
70
|
def direct_recv_queue=(queue)
|
|
68
71
|
@direct_recv_queue = queue
|
|
69
72
|
if queue && @pending_direct
|
|
@@ -93,8 +96,14 @@ module OMQ
|
|
|
93
96
|
alias write_message send_message
|
|
94
97
|
|
|
95
98
|
|
|
99
|
+
# @return [Boolean] always false; inproc pipes are never encrypted
|
|
100
|
+
#
|
|
101
|
+
def encrypted? = false
|
|
102
|
+
|
|
96
103
|
# No-op — inproc has no IO buffer to flush.
|
|
97
104
|
#
|
|
105
|
+
# @return [nil]
|
|
106
|
+
#
|
|
98
107
|
def flush = nil
|
|
99
108
|
|
|
100
109
|
|
|
@@ -143,7 +152,9 @@ module OMQ
|
|
|
143
152
|
end
|
|
144
153
|
|
|
145
154
|
|
|
146
|
-
# Closes this pipe end.
|
|
155
|
+
# Closes this pipe end and sends a nil sentinel to the peer.
|
|
156
|
+
#
|
|
157
|
+
# @return [void]
|
|
147
158
|
#
|
|
148
159
|
def close
|
|
149
160
|
return if @closed
|
data/lib/omq/transport/inproc.rb
CHANGED
|
@@ -19,6 +19,7 @@ module OMQ
|
|
|
19
19
|
#
|
|
20
20
|
COMMAND_TYPES = %i[PUB SUB XPUB XSUB RADIO DISH].freeze
|
|
21
21
|
|
|
22
|
+
|
|
22
23
|
# Global registry of bound inproc endpoints.
|
|
23
24
|
#
|
|
24
25
|
@registry = {}
|
|
@@ -105,11 +106,13 @@ module OMQ
|
|
|
105
106
|
server_engine.connection_ready(server_pipe, endpoint: endpoint)
|
|
106
107
|
end
|
|
107
108
|
|
|
109
|
+
|
|
108
110
|
def needs_commands?(ce, se, ct, st)
|
|
109
111
|
COMMAND_TYPES.include?(ct) || COMMAND_TYPES.include?(st) ||
|
|
110
112
|
ce.options.qos >= 1 || se.options.qos >= 1
|
|
111
113
|
end
|
|
112
114
|
|
|
115
|
+
|
|
113
116
|
def make_pipe_pair(ce, se, ct, st, needs_cmds)
|
|
114
117
|
if needs_cmds
|
|
115
118
|
a_to_b = Async::Queue.new
|
|
@@ -126,6 +129,7 @@ module OMQ
|
|
|
126
129
|
[client, server]
|
|
127
130
|
end
|
|
128
131
|
|
|
132
|
+
|
|
129
133
|
def await_bind(endpoint, engine)
|
|
130
134
|
# Endpoint not bound yet — wait briefly then start background retry.
|
|
131
135
|
# Matches ZMQ 4.x: connect to unbound inproc succeeds silently.
|
|
@@ -163,6 +167,7 @@ module OMQ
|
|
|
163
167
|
end
|
|
164
168
|
end
|
|
165
169
|
|
|
170
|
+
|
|
166
171
|
# A bound inproc endpoint handle.
|
|
167
172
|
#
|
|
168
173
|
class Listener
|
data/lib/omq/transport/ipc.rb
CHANGED
|
@@ -30,6 +30,7 @@ module OMQ
|
|
|
30
30
|
Listener.new(endpoint, server, path)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
|
|
33
34
|
# Connects to an IPC endpoint.
|
|
34
35
|
#
|
|
35
36
|
# @param endpoint [String]
|
|
@@ -51,6 +52,7 @@ module OMQ
|
|
|
51
52
|
endpoint.sub(%r{\Aipc://}, "")
|
|
52
53
|
end
|
|
53
54
|
|
|
55
|
+
|
|
54
56
|
# Converts @ prefix to \0 for abstract namespace.
|
|
55
57
|
#
|
|
56
58
|
def to_socket_path(path)
|
|
@@ -61,6 +63,7 @@ module OMQ
|
|
|
61
63
|
end
|
|
62
64
|
end
|
|
63
65
|
|
|
66
|
+
|
|
64
67
|
# @return [Boolean] true if abstract namespace path
|
|
65
68
|
#
|
|
66
69
|
def abstract?(path)
|
|
@@ -68,6 +71,7 @@ module OMQ
|
|
|
68
71
|
end
|
|
69
72
|
end
|
|
70
73
|
|
|
74
|
+
|
|
71
75
|
# A bound IPC listener.
|
|
72
76
|
#
|
|
73
77
|
class Listener
|
|
@@ -113,7 +117,9 @@ module OMQ
|
|
|
113
117
|
end
|
|
114
118
|
|
|
115
119
|
|
|
116
|
-
# Stops the listener.
|
|
120
|
+
# Stops the listener and removes the socket file.
|
|
121
|
+
#
|
|
122
|
+
# @return [void]
|
|
117
123
|
#
|
|
118
124
|
def stop
|
|
119
125
|
@task&.stop
|
data/lib/omq/transport/tcp.rb
CHANGED
|
@@ -37,12 +37,7 @@ module OMQ
|
|
|
37
37
|
Listener.new(resolved, servers, actual_port)
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
#
|
|
42
|
-
# @param endpoint [String] e.g. "tcp://127.0.0.1:5555"
|
|
43
|
-
# @param engine [Engine]
|
|
44
|
-
# @return [void]
|
|
45
|
-
#
|
|
40
|
+
|
|
46
41
|
# Validates that the endpoint's host can be resolved.
|
|
47
42
|
#
|
|
48
43
|
# @param endpoint [String]
|
|
@@ -54,12 +49,19 @@ module OMQ
|
|
|
54
49
|
end
|
|
55
50
|
|
|
56
51
|
|
|
52
|
+
# Connects to a TCP endpoint.
|
|
53
|
+
#
|
|
54
|
+
# @param endpoint [String] e.g. "tcp://127.0.0.1:5555"
|
|
55
|
+
# @param engine [Engine]
|
|
56
|
+
# @return [void]
|
|
57
|
+
#
|
|
57
58
|
def connect(endpoint, engine)
|
|
58
59
|
host, port = self.parse_endpoint(endpoint)
|
|
59
60
|
sock = TCPSocket.new(host, port)
|
|
60
61
|
engine.handle_connected(IO::Stream::Buffered.wrap(sock), endpoint: endpoint)
|
|
61
62
|
end
|
|
62
63
|
|
|
64
|
+
|
|
63
65
|
# Parses a TCP endpoint URI into host and port.
|
|
64
66
|
#
|
|
65
67
|
# @param endpoint [String]
|
|
@@ -71,6 +73,7 @@ module OMQ
|
|
|
71
73
|
end
|
|
72
74
|
end
|
|
73
75
|
|
|
76
|
+
|
|
74
77
|
# A bound TCP listener.
|
|
75
78
|
#
|
|
76
79
|
class Listener
|
|
@@ -122,7 +125,9 @@ module OMQ
|
|
|
122
125
|
end
|
|
123
126
|
|
|
124
127
|
|
|
125
|
-
# Stops the listener.
|
|
128
|
+
# Stops the listener and closes all server sockets.
|
|
129
|
+
#
|
|
130
|
+
# @return [void]
|
|
126
131
|
#
|
|
127
132
|
def stop
|
|
128
133
|
@tasks.each(&:stop)
|
data/lib/omq/version.rb
CHANGED
data/lib/omq/writable.rb
CHANGED
|
@@ -19,6 +19,7 @@ module OMQ
|
|
|
19
19
|
self
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
|
|
22
23
|
# Sends a message (chainable).
|
|
23
24
|
#
|
|
24
25
|
# @param message [String, Array<String>]
|
|
@@ -46,6 +47,7 @@ module OMQ
|
|
|
46
47
|
parts.freeze
|
|
47
48
|
end
|
|
48
49
|
|
|
50
|
+
|
|
49
51
|
def frozen_binary(str)
|
|
50
52
|
s = str.to_str
|
|
51
53
|
return s if s.frozen? && s.encoding == Encoding::BINARY
|
data/lib/omq.rb
CHANGED
|
@@ -16,7 +16,9 @@ module OMQ
|
|
|
16
16
|
# Raised when an internal pump task crashes unexpectedly.
|
|
17
17
|
# The socket is no longer usable; the original error is available via #cause.
|
|
18
18
|
#
|
|
19
|
-
class SocketDeadError < RuntimeError
|
|
19
|
+
class SocketDeadError < RuntimeError
|
|
20
|
+
end
|
|
21
|
+
|
|
20
22
|
|
|
21
23
|
# Errors raised when a peer disconnects or resets the connection.
|
|
22
24
|
# Not frozen at load time — transport plugins append to this before
|
|
@@ -42,6 +44,7 @@ module OMQ
|
|
|
42
44
|
]
|
|
43
45
|
end
|
|
44
46
|
|
|
47
|
+
|
|
45
48
|
# Transport
|
|
46
49
|
require_relative "omq/transport/inproc"
|
|
47
50
|
require_relative "omq/transport/tcp"
|
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
|
+
version: 0.14.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -13,16 +13,16 @@ dependencies:
|
|
|
13
13
|
name: protocol-zmtp
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '0'
|
|
18
|
+
version: '0.3'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
|
-
- - "
|
|
23
|
+
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '0'
|
|
25
|
+
version: '0.3'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: async
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -69,6 +69,7 @@ files:
|
|
|
69
69
|
- lib/omq/engine.rb
|
|
70
70
|
- lib/omq/engine/connection_setup.rb
|
|
71
71
|
- lib/omq/engine/heartbeat.rb
|
|
72
|
+
- lib/omq/engine/maintenance.rb
|
|
72
73
|
- lib/omq/engine/reconnect.rb
|
|
73
74
|
- lib/omq/engine/recv_pump.rb
|
|
74
75
|
- lib/omq/monitor_event.rb
|