omq 0.11.0 → 0.12.0
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 +95 -0
- data/README.md +3 -1
- data/lib/omq/drop_queue.rb +54 -0
- data/lib/omq/engine.rb +68 -87
- data/lib/omq/monitor_event.rb +16 -0
- data/lib/omq/options.rb +5 -3
- data/lib/omq/pub_sub.rb +9 -8
- data/lib/omq/routing/dealer.rb +1 -1
- data/lib/omq/routing/fan_out.rb +15 -3
- data/lib/omq/routing/pair.rb +2 -2
- data/lib/omq/routing/pull.rb +1 -1
- data/lib/omq/routing/push.rb +2 -0
- data/lib/omq/routing/rep.rb +2 -2
- data/lib/omq/routing/req.rb +8 -3
- data/lib/omq/routing/round_robin.rb +4 -12
- data/lib/omq/routing/router.rb +2 -2
- data/lib/omq/routing/sub.rb +1 -2
- data/lib/omq/routing/xpub.rb +1 -1
- data/lib/omq/routing/xsub.rb +2 -2
- data/lib/omq/routing.rb +41 -11
- data/lib/omq/socket.rb +44 -3
- data/lib/omq/transport/inproc.rb +25 -7
- data/lib/omq/transport/ipc.rb +16 -4
- data/lib/omq/transport/tcp.rb +31 -8
- data/lib/omq/version.rb +1 -1
- data/lib/omq.rb +5 -19
- metadata +3 -16
- data/lib/omq/channel.rb +0 -14
- data/lib/omq/client_server.rb +0 -37
- data/lib/omq/peer.rb +0 -26
- data/lib/omq/radio_dish.rb +0 -74
- data/lib/omq/routing/channel.rb +0 -83
- data/lib/omq/routing/client.rb +0 -56
- data/lib/omq/routing/dish.rb +0 -78
- data/lib/omq/routing/gather.rb +0 -46
- data/lib/omq/routing/peer.rb +0 -101
- data/lib/omq/routing/radio.rb +0 -150
- data/lib/omq/routing/scatter.rb +0 -82
- data/lib/omq/routing/server.rb +0 -101
- data/lib/omq/scatter_gather.rb +0 -23
- data/lib/omq/single_frame.rb +0 -18
- data/lib/omq/transport/tls.rb +0 -146
data/lib/omq/routing/req.rb
CHANGED
|
@@ -12,9 +12,10 @@ module OMQ
|
|
|
12
12
|
# @param engine [Engine]
|
|
13
13
|
#
|
|
14
14
|
def initialize(engine)
|
|
15
|
-
@engine
|
|
16
|
-
@recv_queue
|
|
17
|
-
@tasks
|
|
15
|
+
@engine = engine
|
|
16
|
+
@recv_queue = Routing.build_queue(engine.options.recv_hwm, :block)
|
|
17
|
+
@tasks = []
|
|
18
|
+
@state = :ready # :ready or :waiting_reply
|
|
18
19
|
init_round_robin(engine)
|
|
19
20
|
end
|
|
20
21
|
|
|
@@ -22,6 +23,7 @@ module OMQ
|
|
|
22
23
|
#
|
|
23
24
|
attr_reader :recv_queue, :send_queue
|
|
24
25
|
|
|
26
|
+
|
|
25
27
|
# @param connection [Connection]
|
|
26
28
|
#
|
|
27
29
|
def connection_added(connection)
|
|
@@ -29,6 +31,7 @@ module OMQ
|
|
|
29
31
|
signal_connection_available
|
|
30
32
|
update_direct_pipe
|
|
31
33
|
task = @engine.start_recv_pump(connection, @recv_queue) do |msg|
|
|
34
|
+
@state = :ready
|
|
32
35
|
msg.first&.empty? ? msg[1..] : msg
|
|
33
36
|
end
|
|
34
37
|
@tasks << task if task
|
|
@@ -45,6 +48,8 @@ module OMQ
|
|
|
45
48
|
# @param parts [Array<String>]
|
|
46
49
|
#
|
|
47
50
|
def enqueue(parts)
|
|
51
|
+
raise SocketError, "REQ socket expects send/recv/send/recv order" unless @state == :ready
|
|
52
|
+
@state = :waiting_reply
|
|
48
53
|
enqueue_round_robin(parts)
|
|
49
54
|
end
|
|
50
55
|
|
|
@@ -12,6 +12,9 @@ module OMQ
|
|
|
12
12
|
# their #initialize.
|
|
13
13
|
#
|
|
14
14
|
module RoundRobin
|
|
15
|
+
# @return [Boolean] true when the send pump is idle (not sending a batch)
|
|
16
|
+
def send_pump_idle? = @send_pump_idle
|
|
17
|
+
|
|
15
18
|
private
|
|
16
19
|
|
|
17
20
|
|
|
@@ -23,7 +26,7 @@ module OMQ
|
|
|
23
26
|
@connections = []
|
|
24
27
|
@cycle = @connections.cycle
|
|
25
28
|
@connection_available = Async::Promise.new
|
|
26
|
-
@send_queue =
|
|
29
|
+
@send_queue = Routing.build_queue(engine.options.send_hwm, :block)
|
|
27
30
|
@send_pump_started = false
|
|
28
31
|
@send_pump_idle = true
|
|
29
32
|
@direct_pipe = nil
|
|
@@ -90,13 +93,6 @@ module OMQ
|
|
|
90
93
|
def transform_send(parts) = parts
|
|
91
94
|
|
|
92
95
|
|
|
93
|
-
# Starts the background send pump that dequeues messages
|
|
94
|
-
# and dispatches them round-robin across connections.
|
|
95
|
-
#
|
|
96
|
-
# @return [Boolean] true when the send pump is idle (not sending a batch)
|
|
97
|
-
def send_pump_idle? = @send_pump_idle
|
|
98
|
-
|
|
99
|
-
|
|
100
96
|
def start_send_pump
|
|
101
97
|
@send_pump_started = true
|
|
102
98
|
@tasks << @engine.spawn_pump_task(annotation: "send pump") do
|
|
@@ -144,14 +140,11 @@ module OMQ
|
|
|
144
140
|
@written << conn
|
|
145
141
|
rescue *CONNECTION_LOST
|
|
146
142
|
@engine.connection_lost(conn)
|
|
147
|
-
# Flush what we've written so far
|
|
148
143
|
@written.each do |c|
|
|
149
144
|
c.flush
|
|
150
145
|
rescue *CONNECTION_LOST
|
|
151
|
-
# will be cleaned up
|
|
152
146
|
end
|
|
153
147
|
@written.clear
|
|
154
|
-
# Fall back to send_with_retry for this and remaining
|
|
155
148
|
send_with_retry(parts)
|
|
156
149
|
batch[(i + 1)..].each { |p| send_with_retry(p) }
|
|
157
150
|
return
|
|
@@ -160,7 +153,6 @@ module OMQ
|
|
|
160
153
|
@written.each do |conn|
|
|
161
154
|
conn.flush
|
|
162
155
|
rescue *CONNECTION_LOST
|
|
163
|
-
# will be cleaned up
|
|
164
156
|
end
|
|
165
157
|
end
|
|
166
158
|
end
|
data/lib/omq/routing/router.rb
CHANGED
|
@@ -15,8 +15,8 @@ module OMQ
|
|
|
15
15
|
#
|
|
16
16
|
def initialize(engine)
|
|
17
17
|
@engine = engine
|
|
18
|
-
@recv_queue =
|
|
19
|
-
@send_queue =
|
|
18
|
+
@recv_queue = Routing.build_queue(engine.options.recv_hwm, :block)
|
|
19
|
+
@send_queue = Routing.build_queue(engine.options.send_hwm, :block)
|
|
20
20
|
@connections_by_identity = {}
|
|
21
21
|
@identity_by_connection = {}
|
|
22
22
|
@tasks = []
|
data/lib/omq/routing/sub.rb
CHANGED
|
@@ -13,7 +13,7 @@ module OMQ
|
|
|
13
13
|
def initialize(engine)
|
|
14
14
|
@engine = engine
|
|
15
15
|
@connections = []
|
|
16
|
-
@recv_queue =
|
|
16
|
+
@recv_queue = Routing.build_queue(engine.options.recv_hwm, engine.options.on_mute)
|
|
17
17
|
@subscriptions = Set.new
|
|
18
18
|
@tasks = []
|
|
19
19
|
end
|
|
@@ -26,7 +26,6 @@ module OMQ
|
|
|
26
26
|
#
|
|
27
27
|
def connection_added(connection)
|
|
28
28
|
@connections << connection
|
|
29
|
-
# Send existing subscriptions to new peer
|
|
30
29
|
@subscriptions.each do |prefix|
|
|
31
30
|
connection.send_command(Protocol::ZMTP::Codec::Command.subscribe(prefix))
|
|
32
31
|
end
|
data/lib/omq/routing/xpub.rb
CHANGED
data/lib/omq/routing/xsub.rb
CHANGED
|
@@ -14,8 +14,8 @@ module OMQ
|
|
|
14
14
|
def initialize(engine)
|
|
15
15
|
@engine = engine
|
|
16
16
|
@connections = []
|
|
17
|
-
@recv_queue =
|
|
18
|
-
@send_queue =
|
|
17
|
+
@recv_queue = Routing.build_queue(engine.options.recv_hwm, engine.options.on_mute)
|
|
18
|
+
@send_queue = Routing.build_queue(engine.options.send_hwm, :block)
|
|
19
19
|
@tasks = []
|
|
20
20
|
@send_pump_started = false
|
|
21
21
|
@send_pump_idle = true
|
data/lib/omq/routing.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "async"
|
|
4
4
|
require "async/queue"
|
|
5
5
|
require "async/limited_queue"
|
|
6
|
+
require_relative "drop_queue"
|
|
6
7
|
|
|
7
8
|
module OMQ
|
|
8
9
|
# Routing strategies for each ZMQ socket type.
|
|
@@ -14,6 +15,42 @@ module OMQ
|
|
|
14
15
|
# Shared frozen empty binary string to avoid repeated allocations.
|
|
15
16
|
EMPTY_BINARY = "".b.freeze
|
|
16
17
|
|
|
18
|
+
# Plugin registry for socket types not built into omq.
|
|
19
|
+
# Populated by sister gems via +Routing.register+.
|
|
20
|
+
#
|
|
21
|
+
@registry = {}
|
|
22
|
+
|
|
23
|
+
class << self
|
|
24
|
+
# Registers a routing strategy class for a socket type.
|
|
25
|
+
# Called by omq-draft (and other plugins) at require time.
|
|
26
|
+
#
|
|
27
|
+
# @param socket_type [Symbol] e.g. :RADIO, :CLIENT
|
|
28
|
+
# @param strategy_class [Class]
|
|
29
|
+
#
|
|
30
|
+
def register(socket_type, strategy_class)
|
|
31
|
+
@registry[socket_type] = strategy_class
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Builds a send or recv queue based on the mute strategy.
|
|
36
|
+
#
|
|
37
|
+
# @param hwm [Integer] high water mark
|
|
38
|
+
# @param on_mute [Symbol] :block, :drop_newest, or :drop_oldest
|
|
39
|
+
# @return [Async::LimitedQueue, DropQueue]
|
|
40
|
+
#
|
|
41
|
+
def self.build_queue(hwm, on_mute)
|
|
42
|
+
return Async::Queue.new if hwm.nil? || hwm == 0
|
|
43
|
+
|
|
44
|
+
case on_mute
|
|
45
|
+
when :block
|
|
46
|
+
Async::LimitedQueue.new(hwm)
|
|
47
|
+
when :drop_newest, :drop_oldest
|
|
48
|
+
DropQueue.new(hwm, strategy: on_mute)
|
|
49
|
+
else
|
|
50
|
+
raise ArgumentError, "unknown on_mute strategy: #{on_mute.inspect}"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
17
54
|
# Drains all available messages from +queue+ into +batch+ without
|
|
18
55
|
# blocking. Call after the initial blocking dequeue.
|
|
19
56
|
#
|
|
@@ -49,17 +86,10 @@ module OMQ
|
|
|
49
86
|
when :SUB then Sub
|
|
50
87
|
when :XPUB then XPub
|
|
51
88
|
when :XSUB then XSub
|
|
52
|
-
when :PUSH
|
|
53
|
-
when :PULL
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
when :RADIO then Radio
|
|
57
|
-
when :DISH then Dish
|
|
58
|
-
when :SCATTER then Scatter
|
|
59
|
-
when :GATHER then Gather
|
|
60
|
-
when :PEER then Peer
|
|
61
|
-
when :CHANNEL then Channel
|
|
62
|
-
else raise ArgumentError, "unknown socket type: #{socket_type}"
|
|
89
|
+
when :PUSH then Push
|
|
90
|
+
when :PULL then Pull
|
|
91
|
+
else
|
|
92
|
+
@registry[socket_type] or raise ArgumentError, "unknown socket type: #{socket_type.inspect}"
|
|
63
93
|
end
|
|
64
94
|
end
|
|
65
95
|
end
|
data/lib/omq/socket.rb
CHANGED
|
@@ -36,8 +36,8 @@ module OMQ
|
|
|
36
36
|
:heartbeat_ttl, :heartbeat_ttl=,
|
|
37
37
|
:heartbeat_timeout, :heartbeat_timeout=,
|
|
38
38
|
:max_message_size, :max_message_size=,
|
|
39
|
-
:
|
|
40
|
-
:
|
|
39
|
+
:on_mute, :on_mute=,
|
|
40
|
+
:mechanism, :mechanism=
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
# Creates a new socket and binds it to the given endpoint.
|
|
@@ -141,6 +141,46 @@ module OMQ
|
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
|
|
144
|
+
# Yields lifecycle events for this socket.
|
|
145
|
+
#
|
|
146
|
+
# Spawns a background fiber that reads from an internal event queue.
|
|
147
|
+
# The block receives {MonitorEvent} instances until the socket is
|
|
148
|
+
# closed or the returned task is stopped.
|
|
149
|
+
#
|
|
150
|
+
# @yield [event] called for each lifecycle event
|
|
151
|
+
# @yieldparam event [MonitorEvent]
|
|
152
|
+
# @return [Async::Task] the monitor task (call +#stop+ to end early)
|
|
153
|
+
#
|
|
154
|
+
# @example
|
|
155
|
+
# task = socket.monitor do |event|
|
|
156
|
+
# case event
|
|
157
|
+
# in type: :connected, endpoint:
|
|
158
|
+
# puts "peer up: #{endpoint}"
|
|
159
|
+
# in type: :disconnected, endpoint:
|
|
160
|
+
# puts "peer down: #{endpoint}"
|
|
161
|
+
# end
|
|
162
|
+
# end
|
|
163
|
+
# # later:
|
|
164
|
+
# task.stop
|
|
165
|
+
#
|
|
166
|
+
def monitor(&block)
|
|
167
|
+
ensure_parent_task
|
|
168
|
+
queue = Async::Queue.new
|
|
169
|
+
@engine.monitor_queue = queue
|
|
170
|
+
Reactor.run do
|
|
171
|
+
@engine.parent_task.async(transient: true, annotation: "monitor") do
|
|
172
|
+
while (event = queue.dequeue)
|
|
173
|
+
block.call(event)
|
|
174
|
+
end
|
|
175
|
+
rescue Async::Stop
|
|
176
|
+
ensure
|
|
177
|
+
@engine.monitor_queue = nil
|
|
178
|
+
block.call(MonitorEvent.new(type: :monitor_stopped))
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
|
|
144
184
|
# Disable auto-reconnect for connected endpoints.
|
|
145
185
|
def reconnect_enabled=(val)
|
|
146
186
|
@engine.reconnect_enabled = val
|
|
@@ -226,13 +266,14 @@ module OMQ
|
|
|
226
266
|
#
|
|
227
267
|
def _init_engine(socket_type, linger:, send_hwm: nil, recv_hwm: nil,
|
|
228
268
|
send_timeout: nil, recv_timeout: nil, conflate: false,
|
|
229
|
-
backend: nil)
|
|
269
|
+
on_mute: nil, backend: nil)
|
|
230
270
|
@options = Options.new(linger: linger)
|
|
231
271
|
@options.send_hwm = send_hwm if send_hwm
|
|
232
272
|
@options.recv_hwm = recv_hwm if recv_hwm
|
|
233
273
|
@options.send_timeout = send_timeout if send_timeout
|
|
234
274
|
@options.recv_timeout = recv_timeout if recv_timeout
|
|
235
275
|
@options.conflate = conflate
|
|
276
|
+
@options.on_mute = on_mute if on_mute
|
|
236
277
|
@recv_buffer = []
|
|
237
278
|
@recv_mutex = Mutex.new
|
|
238
279
|
@engine = case backend
|
data/lib/omq/transport/inproc.rb
CHANGED
|
@@ -118,11 +118,12 @@ module OMQ
|
|
|
118
118
|
"incompatible socket types: #{client_type} cannot connect to #{server_type}"
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
-
#
|
|
122
|
-
# over inproc.
|
|
123
|
-
# bypass for data, so no internal queues are needed.
|
|
121
|
+
# PUB/SUB-family types exchange commands (SUBSCRIBE/CANCEL)
|
|
122
|
+
# over inproc. QoS >= 1 needs command queues for ACK/NACK.
|
|
124
123
|
needs_commands = COMMAND_TYPES.include?(client_type) ||
|
|
125
|
-
COMMAND_TYPES.include?(server_type)
|
|
124
|
+
COMMAND_TYPES.include?(server_type) ||
|
|
125
|
+
client_engine.options.qos >= 1 ||
|
|
126
|
+
server_engine.options.qos >= 1
|
|
126
127
|
|
|
127
128
|
if needs_commands
|
|
128
129
|
a_to_b = Async::Queue.new
|
|
@@ -301,13 +302,30 @@ module OMQ
|
|
|
301
302
|
|
|
302
303
|
# Receives a multi-frame message.
|
|
303
304
|
#
|
|
305
|
+
# When a block is given, command items ([:command, cmd]) are
|
|
306
|
+
# yielded as command frames — matching the Protocol::ZMTP::Connection
|
|
307
|
+
# interface. Without a block, commands are silently skipped if
|
|
308
|
+
# the pipe has command queues.
|
|
309
|
+
#
|
|
304
310
|
# @return [Array<String>]
|
|
305
311
|
# @raise [EOFError] if closed
|
|
306
312
|
#
|
|
307
313
|
def receive_message
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
314
|
+
loop do
|
|
315
|
+
item = @receive_queue.dequeue
|
|
316
|
+
raise EOFError, "connection closed" if item.nil?
|
|
317
|
+
|
|
318
|
+
if item.is_a?(Array) && item.first == :command
|
|
319
|
+
if block_given?
|
|
320
|
+
cmd = item[1]
|
|
321
|
+
frame = Protocol::ZMTP::Codec::Frame.new(cmd.to_body, command: true)
|
|
322
|
+
yield frame
|
|
323
|
+
end
|
|
324
|
+
next
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
return item
|
|
328
|
+
end
|
|
311
329
|
end
|
|
312
330
|
|
|
313
331
|
|
data/lib/omq/transport/ipc.rb
CHANGED
|
@@ -92,12 +92,24 @@ module OMQ
|
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
|
|
95
|
-
#
|
|
95
|
+
# Spawns an accept loop task under +parent_task+.
|
|
96
|
+
# Yields an IO::Stream-wrapped client socket for each accepted connection.
|
|
96
97
|
#
|
|
97
|
-
# @param
|
|
98
|
+
# @param parent_task [Async::Task]
|
|
99
|
+
# @yieldparam io [IO::Stream::Buffered]
|
|
98
100
|
#
|
|
99
|
-
def
|
|
100
|
-
@task =
|
|
101
|
+
def start_accept_loops(parent_task, &on_accepted)
|
|
102
|
+
@task = parent_task.async(transient: true, annotation: "ipc accept #{@endpoint}") do
|
|
103
|
+
loop do
|
|
104
|
+
client = @server.accept
|
|
105
|
+
Async::Task.current.defer_stop { on_accepted.call(IO::Stream::Buffered.wrap(client)) }
|
|
106
|
+
end
|
|
107
|
+
rescue Async::Stop
|
|
108
|
+
rescue IOError
|
|
109
|
+
# server closed
|
|
110
|
+
ensure
|
|
111
|
+
@server.close rescue nil
|
|
112
|
+
end
|
|
101
113
|
end
|
|
102
114
|
|
|
103
115
|
|
data/lib/omq/transport/tcp.rb
CHANGED
|
@@ -17,7 +17,7 @@ module OMQ
|
|
|
17
17
|
# @return [Listener]
|
|
18
18
|
#
|
|
19
19
|
def bind(endpoint, engine)
|
|
20
|
-
host, port = parse_endpoint(endpoint)
|
|
20
|
+
host, port = self.parse_endpoint(endpoint)
|
|
21
21
|
host = "0.0.0.0" if host == "*"
|
|
22
22
|
|
|
23
23
|
addrs = Addrinfo.getaddrinfo(host, port, nil, :STREAM, nil, ::Socket::AI_PASSIVE)
|
|
@@ -43,14 +43,23 @@ module OMQ
|
|
|
43
43
|
# @param engine [Engine]
|
|
44
44
|
# @return [void]
|
|
45
45
|
#
|
|
46
|
+
# Validates that the endpoint's host can be resolved.
|
|
47
|
+
#
|
|
48
|
+
# @param endpoint [String]
|
|
49
|
+
# @return [void]
|
|
50
|
+
#
|
|
51
|
+
def validate_endpoint!(endpoint)
|
|
52
|
+
host, _port = parse_endpoint(endpoint)
|
|
53
|
+
Addrinfo.getaddrinfo(host, nil, nil, :STREAM) if host
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
46
57
|
def connect(endpoint, engine)
|
|
47
|
-
host, port = parse_endpoint(endpoint)
|
|
58
|
+
host, port = self.parse_endpoint(endpoint)
|
|
48
59
|
sock = TCPSocket.new(host, port)
|
|
49
60
|
engine.handle_connected(IO::Stream::Buffered.wrap(sock), endpoint: endpoint)
|
|
50
61
|
end
|
|
51
62
|
|
|
52
|
-
private
|
|
53
|
-
|
|
54
63
|
# Parses a TCP endpoint URI into host and port.
|
|
55
64
|
#
|
|
56
65
|
# @param endpoint [String]
|
|
@@ -90,12 +99,26 @@ module OMQ
|
|
|
90
99
|
end
|
|
91
100
|
|
|
92
101
|
|
|
93
|
-
#
|
|
102
|
+
# Spawns accept loop tasks under +parent_task+.
|
|
103
|
+
# Yields an IO::Stream-wrapped client socket for each accepted connection.
|
|
94
104
|
#
|
|
95
|
-
# @param
|
|
105
|
+
# @param parent_task [Async::Task]
|
|
106
|
+
# @yieldparam io [IO::Stream::Buffered]
|
|
96
107
|
#
|
|
97
|
-
def
|
|
98
|
-
@tasks =
|
|
108
|
+
def start_accept_loops(parent_task, &on_accepted)
|
|
109
|
+
@tasks = @servers.map do |server|
|
|
110
|
+
parent_task.async(transient: true, annotation: "tcp accept #{@endpoint}") do
|
|
111
|
+
loop do
|
|
112
|
+
client = server.accept
|
|
113
|
+
Async::Task.current.defer_stop { on_accepted.call(IO::Stream::Buffered.wrap(client)) }
|
|
114
|
+
end
|
|
115
|
+
rescue Async::Stop
|
|
116
|
+
rescue IOError
|
|
117
|
+
# server closed
|
|
118
|
+
ensure
|
|
119
|
+
server.close rescue nil
|
|
120
|
+
end
|
|
121
|
+
end
|
|
99
122
|
end
|
|
100
123
|
|
|
101
124
|
|
data/lib/omq/version.rb
CHANGED
data/lib/omq.rb
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
require "protocol/zmtp"
|
|
10
10
|
require "io/stream"
|
|
11
|
-
require "openssl"
|
|
12
11
|
|
|
13
12
|
require_relative "omq/version"
|
|
13
|
+
require_relative "omq/monitor_event"
|
|
14
14
|
|
|
15
15
|
module OMQ
|
|
16
16
|
# Raised when an internal pump task crashes unexpectedly.
|
|
@@ -19,6 +19,8 @@ module OMQ
|
|
|
19
19
|
class SocketDeadError < RuntimeError; end
|
|
20
20
|
|
|
21
21
|
# Errors raised when a peer disconnects or resets the connection.
|
|
22
|
+
# Not frozen at load time — transport plugins append to this before
|
|
23
|
+
# the first bind/connect, which freezes both arrays.
|
|
22
24
|
CONNECTION_LOST = [
|
|
23
25
|
EOFError,
|
|
24
26
|
IOError,
|
|
@@ -27,8 +29,7 @@ module OMQ
|
|
|
27
29
|
Errno::ECONNABORTED,
|
|
28
30
|
Errno::ENOTCONN,
|
|
29
31
|
IO::Stream::ConnectionResetError,
|
|
30
|
-
|
|
31
|
-
].freeze
|
|
32
|
+
]
|
|
32
33
|
|
|
33
34
|
# Errors raised when a peer cannot be reached.
|
|
34
35
|
CONNECTION_FAILED = [
|
|
@@ -38,13 +39,12 @@ module OMQ
|
|
|
38
39
|
Errno::EHOSTUNREACH,
|
|
39
40
|
Errno::ENETUNREACH,
|
|
40
41
|
Socket::ResolutionError,
|
|
41
|
-
]
|
|
42
|
+
]
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
# Transport
|
|
45
46
|
require_relative "omq/transport/inproc"
|
|
46
47
|
require_relative "omq/transport/tcp"
|
|
47
|
-
require_relative "omq/transport/tls"
|
|
48
48
|
require_relative "omq/transport/ipc"
|
|
49
49
|
|
|
50
50
|
# Core
|
|
@@ -64,15 +64,6 @@ require_relative "omq/routing/xpub"
|
|
|
64
64
|
require_relative "omq/routing/xsub"
|
|
65
65
|
require_relative "omq/routing/push"
|
|
66
66
|
require_relative "omq/routing/pull"
|
|
67
|
-
require_relative "omq/routing/scatter"
|
|
68
|
-
require_relative "omq/routing/gather"
|
|
69
|
-
require_relative "omq/routing/channel"
|
|
70
|
-
require_relative "omq/routing/client"
|
|
71
|
-
require_relative "omq/routing/server"
|
|
72
|
-
require_relative "omq/routing/radio"
|
|
73
|
-
require_relative "omq/routing/dish"
|
|
74
|
-
require_relative "omq/routing/peer"
|
|
75
|
-
require_relative "omq/single_frame"
|
|
76
67
|
require_relative "omq/engine"
|
|
77
68
|
require_relative "omq/queue_interface"
|
|
78
69
|
require_relative "omq/readable"
|
|
@@ -85,11 +76,6 @@ require_relative "omq/router_dealer"
|
|
|
85
76
|
require_relative "omq/pub_sub"
|
|
86
77
|
require_relative "omq/push_pull"
|
|
87
78
|
require_relative "omq/pair"
|
|
88
|
-
require_relative "omq/scatter_gather"
|
|
89
|
-
require_relative "omq/channel"
|
|
90
|
-
require_relative "omq/client_server"
|
|
91
|
-
require_relative "omq/radio_dish"
|
|
92
|
-
require_relative "omq/peer"
|
|
93
79
|
|
|
94
80
|
# For the purists.
|
|
95
81
|
ØMQ = OMQ
|
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.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -65,49 +65,36 @@ files:
|
|
|
65
65
|
- LICENSE
|
|
66
66
|
- README.md
|
|
67
67
|
- lib/omq.rb
|
|
68
|
-
- lib/omq/
|
|
69
|
-
- lib/omq/client_server.rb
|
|
68
|
+
- lib/omq/drop_queue.rb
|
|
70
69
|
- lib/omq/engine.rb
|
|
70
|
+
- lib/omq/monitor_event.rb
|
|
71
71
|
- lib/omq/options.rb
|
|
72
72
|
- lib/omq/pair.rb
|
|
73
|
-
- lib/omq/peer.rb
|
|
74
73
|
- lib/omq/pub_sub.rb
|
|
75
74
|
- lib/omq/push_pull.rb
|
|
76
75
|
- lib/omq/queue_interface.rb
|
|
77
|
-
- lib/omq/radio_dish.rb
|
|
78
76
|
- lib/omq/reactor.rb
|
|
79
77
|
- lib/omq/readable.rb
|
|
80
78
|
- lib/omq/req_rep.rb
|
|
81
79
|
- lib/omq/router_dealer.rb
|
|
82
80
|
- lib/omq/routing.rb
|
|
83
|
-
- lib/omq/routing/channel.rb
|
|
84
|
-
- lib/omq/routing/client.rb
|
|
85
81
|
- lib/omq/routing/dealer.rb
|
|
86
|
-
- lib/omq/routing/dish.rb
|
|
87
82
|
- lib/omq/routing/fan_out.rb
|
|
88
|
-
- lib/omq/routing/gather.rb
|
|
89
83
|
- lib/omq/routing/pair.rb
|
|
90
|
-
- lib/omq/routing/peer.rb
|
|
91
84
|
- lib/omq/routing/pub.rb
|
|
92
85
|
- lib/omq/routing/pull.rb
|
|
93
86
|
- lib/omq/routing/push.rb
|
|
94
|
-
- lib/omq/routing/radio.rb
|
|
95
87
|
- lib/omq/routing/rep.rb
|
|
96
88
|
- lib/omq/routing/req.rb
|
|
97
89
|
- lib/omq/routing/round_robin.rb
|
|
98
90
|
- lib/omq/routing/router.rb
|
|
99
|
-
- lib/omq/routing/scatter.rb
|
|
100
|
-
- lib/omq/routing/server.rb
|
|
101
91
|
- lib/omq/routing/sub.rb
|
|
102
92
|
- lib/omq/routing/xpub.rb
|
|
103
93
|
- lib/omq/routing/xsub.rb
|
|
104
|
-
- lib/omq/scatter_gather.rb
|
|
105
|
-
- lib/omq/single_frame.rb
|
|
106
94
|
- lib/omq/socket.rb
|
|
107
95
|
- lib/omq/transport/inproc.rb
|
|
108
96
|
- lib/omq/transport/ipc.rb
|
|
109
97
|
- lib/omq/transport/tcp.rb
|
|
110
|
-
- lib/omq/transport/tls.rb
|
|
111
98
|
- lib/omq/version.rb
|
|
112
99
|
- lib/omq/writable.rb
|
|
113
100
|
homepage: https://github.com/zeromq/omq
|
data/lib/omq/channel.rb
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module OMQ
|
|
4
|
-
class CHANNEL < Socket
|
|
5
|
-
include Readable
|
|
6
|
-
include Writable
|
|
7
|
-
include SingleFrame
|
|
8
|
-
|
|
9
|
-
def initialize(endpoints = nil, linger: 0, backend: nil)
|
|
10
|
-
_init_engine(:CHANNEL, linger: linger, backend: backend)
|
|
11
|
-
_attach(endpoints, default: :connect)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
data/lib/omq/client_server.rb
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module OMQ
|
|
4
|
-
class CLIENT < Socket
|
|
5
|
-
include Readable
|
|
6
|
-
include Writable
|
|
7
|
-
include SingleFrame
|
|
8
|
-
|
|
9
|
-
def initialize(endpoints = nil, linger: 0, backend: nil)
|
|
10
|
-
_init_engine(:CLIENT, linger: linger, backend: backend)
|
|
11
|
-
_attach(endpoints, default: :connect)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
class SERVER < Socket
|
|
16
|
-
include Readable
|
|
17
|
-
include Writable
|
|
18
|
-
include SingleFrame
|
|
19
|
-
|
|
20
|
-
def initialize(endpoints = nil, linger: 0, backend: nil)
|
|
21
|
-
_init_engine(:SERVER, linger: linger, backend: backend)
|
|
22
|
-
_attach(endpoints, default: :bind)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Sends a message to a specific peer by routing ID.
|
|
26
|
-
#
|
|
27
|
-
# @param routing_id [String] 4-byte routing ID
|
|
28
|
-
# @param message [String] message body
|
|
29
|
-
# @return [self]
|
|
30
|
-
#
|
|
31
|
-
def send_to(routing_id, message)
|
|
32
|
-
parts = [routing_id.b.freeze, message.b.freeze]
|
|
33
|
-
with_timeout(@options.write_timeout) { @engine.enqueue_send(parts) }
|
|
34
|
-
self
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
data/lib/omq/peer.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module OMQ
|
|
4
|
-
class PEER < Socket
|
|
5
|
-
include Readable
|
|
6
|
-
include Writable
|
|
7
|
-
include SingleFrame
|
|
8
|
-
|
|
9
|
-
def initialize(endpoints = nil, linger: 0, backend: nil)
|
|
10
|
-
_init_engine(:PEER, linger: linger, backend: backend)
|
|
11
|
-
_attach(endpoints, default: :connect)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Sends a message to a specific peer by routing ID.
|
|
15
|
-
#
|
|
16
|
-
# @param routing_id [String] 4-byte routing ID
|
|
17
|
-
# @param message [String] message body
|
|
18
|
-
# @return [self]
|
|
19
|
-
#
|
|
20
|
-
def send_to(routing_id, message)
|
|
21
|
-
parts = [routing_id.b.freeze, message.b.freeze]
|
|
22
|
-
with_timeout(@options.write_timeout) { @engine.enqueue_send(parts) }
|
|
23
|
-
self
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|