omq 0.22.1 → 0.24.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 +162 -0
- data/README.md +17 -21
- data/lib/omq/channel.rb +35 -0
- data/lib/omq/client_server.rb +72 -0
- data/lib/omq/constants.rb +68 -0
- data/lib/omq/engine/connection_lifecycle.rb +22 -8
- data/lib/omq/engine/heartbeat.rb +3 -4
- data/lib/omq/engine/maintenance.rb +4 -5
- data/lib/omq/engine/reconnect.rb +12 -11
- data/lib/omq/engine/recv_pump.rb +10 -10
- data/lib/omq/engine/socket_lifecycle.rb +26 -9
- data/lib/omq/engine.rb +202 -90
- data/lib/omq/peer.rb +49 -0
- data/lib/omq/pub_sub.rb +2 -2
- data/lib/omq/radio_dish.rb +122 -0
- data/lib/omq/reactor.rb +14 -5
- data/lib/omq/readable.rb +5 -1
- data/lib/omq/routing/channel.rb +110 -0
- data/lib/omq/routing/client.rb +70 -0
- data/lib/omq/routing/conn_send_pump.rb +5 -8
- data/lib/omq/routing/dealer.rb +3 -15
- data/lib/omq/routing/dish.rb +94 -0
- data/lib/omq/routing/fan_out.rb +12 -16
- data/lib/omq/routing/gather.rb +60 -0
- data/lib/omq/routing/pair.rb +7 -26
- data/lib/omq/routing/peer.rb +95 -0
- data/lib/omq/routing/pub.rb +2 -13
- data/lib/omq/routing/pull.rb +3 -15
- data/lib/omq/routing/push.rb +4 -13
- data/lib/omq/routing/radio.rb +187 -0
- data/lib/omq/routing/rep.rb +5 -19
- data/lib/omq/routing/req.rb +6 -18
- data/lib/omq/routing/round_robin.rb +15 -19
- data/lib/omq/routing/router.rb +5 -19
- data/lib/omq/routing/scatter.rb +76 -0
- data/lib/omq/routing/server.rb +90 -0
- data/lib/omq/routing/sub.rb +3 -15
- data/lib/omq/routing/xpub.rb +2 -13
- data/lib/omq/routing/xsub.rb +8 -25
- data/lib/omq/scatter_gather.rb +56 -0
- data/lib/omq/socket.rb +8 -23
- data/lib/omq/transport/inproc/{direct_pipe.rb → pipe.rb} +26 -24
- data/lib/omq/transport/inproc.rb +22 -14
- data/lib/omq/transport/ipc.rb +41 -13
- data/lib/omq/transport/tcp.rb +59 -23
- data/lib/omq/transport/udp.rb +281 -0
- data/lib/omq/version.rb +1 -1
- data/lib/omq/writable.rb +11 -42
- data/lib/omq.rb +9 -64
- metadata +17 -3
- data/lib/omq/monitor_event.rb +0 -16
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "socket"
|
|
4
|
+
require "uri"
|
|
5
|
+
require "set"
|
|
6
|
+
|
|
7
|
+
module OMQ
|
|
8
|
+
module Transport
|
|
9
|
+
# UDP transport for RADIO/DISH sockets.
|
|
10
|
+
#
|
|
11
|
+
# Connectionless, datagram-based. No ZMTP handshake.
|
|
12
|
+
# DISH binds and receives; RADIO connects and sends.
|
|
13
|
+
#
|
|
14
|
+
# Wire format per datagram:
|
|
15
|
+
# flags (1 byte = 0x01) | group_size (1 byte) | group (n bytes) | body
|
|
16
|
+
#
|
|
17
|
+
module UDP
|
|
18
|
+
Engine.transports["udp"] = self
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
MAX_DATAGRAM_SIZE = 65507
|
|
22
|
+
|
|
23
|
+
class << self
|
|
24
|
+
# Creates a bound UDP listener for a DISH socket.
|
|
25
|
+
#
|
|
26
|
+
# @param endpoint [String] e.g. "udp://*:5555" or "udp://127.0.0.1:5555"
|
|
27
|
+
# @param engine [Engine]
|
|
28
|
+
# @return [Listener]
|
|
29
|
+
#
|
|
30
|
+
def listener(endpoint, engine, **)
|
|
31
|
+
host, port = parse_endpoint(endpoint)
|
|
32
|
+
host = "0.0.0.0" if host == "*"
|
|
33
|
+
socket = UDPSocket.new
|
|
34
|
+
socket.bind(host, port)
|
|
35
|
+
Listener.new(endpoint, socket, engine)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Creates a UDP dialer for a RADIO socket.
|
|
40
|
+
#
|
|
41
|
+
# @param endpoint [String] e.g. "udp://127.0.0.1:5555"
|
|
42
|
+
# @param engine [Engine]
|
|
43
|
+
# @return [Dialer]
|
|
44
|
+
#
|
|
45
|
+
def dialer(endpoint, engine, **)
|
|
46
|
+
Dialer.new(endpoint, engine)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# @param endpoint [String]
|
|
51
|
+
# @return [Array(String, Integer)]
|
|
52
|
+
#
|
|
53
|
+
def parse_endpoint(endpoint)
|
|
54
|
+
uri = URI.parse(endpoint)
|
|
55
|
+
[uri.hostname, uri.port]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# Encodes a group + body into a UDP datagram.
|
|
60
|
+
#
|
|
61
|
+
# @param group [String]
|
|
62
|
+
# @param body [String]
|
|
63
|
+
# @return [String] binary datagram
|
|
64
|
+
#
|
|
65
|
+
def encode_datagram(group, body)
|
|
66
|
+
g = group.b
|
|
67
|
+
b = body.b
|
|
68
|
+
[0x01, g.bytesize].pack("CC") + g + b
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# Decodes a UDP datagram into [group, body].
|
|
73
|
+
#
|
|
74
|
+
# @param data [String] raw datagram bytes
|
|
75
|
+
# @return [Array(String, String), nil] nil if malformed
|
|
76
|
+
#
|
|
77
|
+
def decode_datagram(data)
|
|
78
|
+
return nil if data.bytesize < 2
|
|
79
|
+
return nil unless data.getbyte(0) & 0x01 == 0x01
|
|
80
|
+
gs = data.getbyte(1)
|
|
81
|
+
return nil if data.bytesize < 2 + gs
|
|
82
|
+
group = data.byteslice(2, gs)
|
|
83
|
+
body = data.byteslice(2 + gs, data.bytesize - 2 - gs)
|
|
84
|
+
[group, body]
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# A UDP dialer — registers a single RadioConnection with the engine.
|
|
90
|
+
#
|
|
91
|
+
# UDP is connectionless; #connect is a one-shot registration.
|
|
92
|
+
# The reconnect loop will break out after the first successful call.
|
|
93
|
+
#
|
|
94
|
+
class Dialer
|
|
95
|
+
# @return [String] the endpoint this dialer sends to
|
|
96
|
+
#
|
|
97
|
+
attr_reader :endpoint
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# @param endpoint [String]
|
|
101
|
+
# @param engine [Engine]
|
|
102
|
+
#
|
|
103
|
+
def initialize(endpoint, engine)
|
|
104
|
+
@endpoint = endpoint
|
|
105
|
+
@engine = engine
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# Registers a RadioConnection with the engine.
|
|
110
|
+
#
|
|
111
|
+
# @return [void]
|
|
112
|
+
#
|
|
113
|
+
def connect
|
|
114
|
+
host, port = UDP.parse_endpoint(@endpoint)
|
|
115
|
+
socket = UDPSocket.new
|
|
116
|
+
conn = RadioConnection.new(socket, host, port)
|
|
117
|
+
@engine.connection_ready(conn, endpoint: @endpoint)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# Outgoing UDP connection for RADIO sockets.
|
|
124
|
+
#
|
|
125
|
+
# Intentionally does not implement #read_frame — this signals
|
|
126
|
+
# Routing::Radio to skip the group listener and use ANY_GROUPS.
|
|
127
|
+
#
|
|
128
|
+
class RadioConnection
|
|
129
|
+
# @param socket [UDPSocket]
|
|
130
|
+
# @param host [String]
|
|
131
|
+
# @param port [Integer]
|
|
132
|
+
#
|
|
133
|
+
def initialize(socket, host, port)
|
|
134
|
+
@socket = socket
|
|
135
|
+
@host = host
|
|
136
|
+
@port = port
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# Encodes and sends a datagram.
|
|
141
|
+
#
|
|
142
|
+
# @param parts [Array<String>] [group, body]
|
|
143
|
+
#
|
|
144
|
+
def write_message(parts)
|
|
145
|
+
group, body = parts
|
|
146
|
+
datagram = UDP.encode_datagram(group.to_s, body.to_s)
|
|
147
|
+
@socket.send(datagram, 0, @host, @port)
|
|
148
|
+
rescue Errno::ECONNREFUSED, Errno::ENETUNREACH
|
|
149
|
+
# UDP fire-and-forget — drop silently
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
alias send_message write_message
|
|
153
|
+
|
|
154
|
+
# No-op; UDP datagrams are sent immediately.
|
|
155
|
+
def flush
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# Whether this connection uses CURVE encryption.
|
|
160
|
+
#
|
|
161
|
+
# @return [Boolean] always false
|
|
162
|
+
def curve?
|
|
163
|
+
false
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# Closes the underlying UDP socket.
|
|
168
|
+
def close
|
|
169
|
+
@socket.close rescue nil
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# Incoming UDP connection for DISH sockets.
|
|
175
|
+
#
|
|
176
|
+
# Tracks joined groups locally. JOIN/LEAVE commands from the
|
|
177
|
+
# DISH routing strategy are intercepted via #send_command and
|
|
178
|
+
# never transmitted on the wire.
|
|
179
|
+
#
|
|
180
|
+
class DishConnection
|
|
181
|
+
# @param socket [UDPSocket] bound socket
|
|
182
|
+
#
|
|
183
|
+
def initialize(socket)
|
|
184
|
+
@socket = socket
|
|
185
|
+
@groups = Set.new
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# Receives one matching datagram, blocking until available.
|
|
190
|
+
#
|
|
191
|
+
# Async-safe: rescues IO::WaitReadable and yields to the
|
|
192
|
+
# fiber scheduler via #wait_readable.
|
|
193
|
+
#
|
|
194
|
+
# @return [Array<String>] [group, body], both binary-frozen
|
|
195
|
+
#
|
|
196
|
+
def receive_message
|
|
197
|
+
loop do
|
|
198
|
+
data, = @socket.recvfrom_nonblock(MAX_DATAGRAM_SIZE)
|
|
199
|
+
parts = UDP.decode_datagram(data)
|
|
200
|
+
next unless parts
|
|
201
|
+
group, body = parts
|
|
202
|
+
next unless @groups.include?(group.b)
|
|
203
|
+
return [group, body]
|
|
204
|
+
rescue IO::WaitReadable
|
|
205
|
+
@socket.wait_readable
|
|
206
|
+
retry
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
# Handles JOIN/LEAVE commands locally; nothing is sent on the wire.
|
|
212
|
+
#
|
|
213
|
+
# @param cmd [Protocol::ZMTP::Codec::Command]
|
|
214
|
+
#
|
|
215
|
+
def send_command(cmd)
|
|
216
|
+
case cmd.name
|
|
217
|
+
when "JOIN"
|
|
218
|
+
@groups << cmd.data.b.freeze
|
|
219
|
+
when "LEAVE"
|
|
220
|
+
@groups.delete(cmd.data.b)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# Whether this connection uses CURVE encryption.
|
|
226
|
+
#
|
|
227
|
+
# @return [Boolean] always false
|
|
228
|
+
def curve?
|
|
229
|
+
false
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
# Closes the underlying UDP socket.
|
|
234
|
+
def close
|
|
235
|
+
@socket.close rescue nil
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
# Bound UDP listener for DISH sockets.
|
|
241
|
+
#
|
|
242
|
+
# Unlike TCP/IPC listeners, there is no accept loop — a single
|
|
243
|
+
# DishConnection is registered directly with the engine, bypassing
|
|
244
|
+
# the ZMTP handshake path.
|
|
245
|
+
#
|
|
246
|
+
class Listener
|
|
247
|
+
# @return [String] bound endpoint
|
|
248
|
+
#
|
|
249
|
+
attr_reader :endpoint
|
|
250
|
+
|
|
251
|
+
# @param endpoint [String]
|
|
252
|
+
# @param socket [UDPSocket]
|
|
253
|
+
# @param engine [Engine]
|
|
254
|
+
#
|
|
255
|
+
def initialize(endpoint, socket, engine)
|
|
256
|
+
@endpoint = endpoint
|
|
257
|
+
@socket = socket
|
|
258
|
+
@engine = engine
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
# Registers a DishConnection with the engine.
|
|
263
|
+
# The on_accepted block is intentionally ignored — no ZMTP handshake.
|
|
264
|
+
#
|
|
265
|
+
# @param parent_task [Async::Task] (unused)
|
|
266
|
+
#
|
|
267
|
+
def start_accept_loops(parent_task, &_on_accepted)
|
|
268
|
+
conn = DishConnection.new(@socket)
|
|
269
|
+
@engine.connection_ready(conn, endpoint: @endpoint)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
# Stops the listener.
|
|
274
|
+
#
|
|
275
|
+
def stop
|
|
276
|
+
@socket.close rescue nil
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
data/lib/omq/version.rb
CHANGED
data/lib/omq/writable.rb
CHANGED
|
@@ -9,19 +9,25 @@ module OMQ
|
|
|
9
9
|
include QueueWritable
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
EMPTY_PART = "".b.freeze
|
|
13
|
-
|
|
14
|
-
|
|
15
12
|
# Sends a message.
|
|
16
13
|
#
|
|
14
|
+
# Caller owns the message parts. Don't mutate them after sending — especially
|
|
15
|
+
# with inproc transport or PUB fan-out, where a single reference can be shared
|
|
16
|
+
# across peers and read later by the send pump.
|
|
17
|
+
#
|
|
17
18
|
# @param message [String, Array<String>] message parts
|
|
18
19
|
# @return [self]
|
|
19
20
|
# @raise [IO::TimeoutError] if write_timeout exceeded
|
|
20
21
|
#
|
|
21
22
|
def send(message)
|
|
22
|
-
parts =
|
|
23
|
+
parts = message.is_a?(Array) ? message : [message]
|
|
24
|
+
raise ArgumentError, "message has no parts" if parts.empty?
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
if @engine.on_io_thread?
|
|
27
|
+
Reactor.run(timeout: @options.write_timeout) { @engine.enqueue_send(parts) }
|
|
28
|
+
elsif (timeout = @options.write_timeout)
|
|
29
|
+
Async::Task.current.with_timeout(timeout, IO::TimeoutError) { @engine.enqueue_send(parts) }
|
|
30
|
+
else
|
|
25
31
|
@engine.enqueue_send(parts)
|
|
26
32
|
end
|
|
27
33
|
|
|
@@ -48,42 +54,5 @@ module OMQ
|
|
|
48
54
|
true
|
|
49
55
|
end
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# Converts a message into a frozen array of frozen binary strings.
|
|
56
|
-
#
|
|
57
|
-
# @param message [String, Array<String>]
|
|
58
|
-
# @return [Array<String>] frozen array of frozen binary strings
|
|
59
|
-
#
|
|
60
|
-
def freeze_message(message)
|
|
61
|
-
parts = message.is_a?(Array) ? message : [message]
|
|
62
|
-
raise ArgumentError, "message has no parts" if parts.empty?
|
|
63
|
-
|
|
64
|
-
all_ready = parts.all? { |p| p.is_a?(String) && p.frozen? && p.encoding == Encoding::BINARY }
|
|
65
|
-
|
|
66
|
-
# Already a frozen array of frozen binary strings → return as-is.
|
|
67
|
-
return parts if all_ready && parts.frozen?
|
|
68
|
-
|
|
69
|
-
# Items are ready; just freeze the outer array.
|
|
70
|
-
return parts.freeze if all_ready
|
|
71
|
-
|
|
72
|
-
# Items need conversion. Mutate in place when we can.
|
|
73
|
-
if parts.frozen?
|
|
74
|
-
parts.map { |p| frozen_binary(p) }.freeze
|
|
75
|
-
else
|
|
76
|
-
parts.map! { |p| frozen_binary(p) }.freeze
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def frozen_binary(obj)
|
|
82
|
-
return EMPTY_PART if obj.nil?
|
|
83
|
-
s = obj.to_s
|
|
84
|
-
return s if s.frozen? && s.encoding == Encoding::BINARY
|
|
85
|
-
s.b.freeze
|
|
86
|
-
end
|
|
87
|
-
|
|
88
57
|
end
|
|
89
58
|
end
|
data/lib/omq.rb
CHANGED
|
@@ -1,74 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# OMQ — pure Ruby ZeroMQ (ZMTP 3.1).
|
|
4
|
-
#
|
|
5
|
-
# Socket types live directly under OMQ:: for a clean API:
|
|
6
|
-
# OMQ::PUSH, OMQ::PULL, OMQ::PUB, OMQ::SUB, etc.
|
|
7
|
-
#
|
|
8
|
-
|
|
9
3
|
require "protocol/zmtp"
|
|
10
4
|
require "io/stream"
|
|
11
5
|
|
|
12
|
-
require_relative "omq/version"
|
|
13
|
-
require_relative "omq/monitor_event"
|
|
14
|
-
|
|
15
|
-
module OMQ
|
|
16
|
-
# When OMQ_DEBUG is set, silent rescue clauses print the exception
|
|
17
|
-
# to stderr so transport/engine bugs surface immediately.
|
|
18
|
-
DEBUG = !!ENV["OMQ_DEBUG"]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# Raised when an internal pump task crashes unexpectedly.
|
|
22
|
-
# The socket is no longer usable; the original error is available via #cause.
|
|
23
|
-
#
|
|
24
|
-
class SocketDeadError < RuntimeError
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# Errors raised when a peer disconnects or resets the connection.
|
|
29
|
-
# Not frozen at load time — transport plugins append to this before
|
|
30
|
-
# the first bind/connect, which freezes both arrays.
|
|
31
|
-
CONNECTION_LOST = [
|
|
32
|
-
EOFError,
|
|
33
|
-
IOError,
|
|
34
|
-
Errno::EPIPE,
|
|
35
|
-
Errno::ECONNRESET,
|
|
36
|
-
Errno::ECONNABORTED,
|
|
37
|
-
Errno::ENOTCONN,
|
|
38
|
-
IO::Stream::ConnectionResetError,
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
# Errors raised when a peer cannot be reached.
|
|
43
|
-
CONNECTION_FAILED = [
|
|
44
|
-
Errno::ECONNREFUSED,
|
|
45
|
-
Errno::ENOENT,
|
|
46
|
-
Errno::ETIMEDOUT,
|
|
47
|
-
Errno::EHOSTUNREACH,
|
|
48
|
-
Errno::ENETUNREACH,
|
|
49
|
-
Errno::EPROTOTYPE, # IPC: existing socket file is SOCK_DGRAM, not SOCK_STREAM
|
|
50
|
-
Socket::ResolutionError,
|
|
51
|
-
]
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
# Freezes module-level state so OMQ sockets can be used inside Ractors.
|
|
55
|
-
# Call this once before spawning any Ractors that create OMQ sockets.
|
|
56
|
-
#
|
|
57
|
-
def self.freeze_for_ractors!
|
|
58
|
-
CONNECTION_LOST.freeze
|
|
59
|
-
CONNECTION_FAILED.freeze
|
|
60
|
-
Engine.transports.freeze
|
|
61
|
-
Routing.registry.freeze
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
# Transport
|
|
67
|
-
require_relative "omq/transport/inproc"
|
|
68
|
-
require_relative "omq/transport/tcp"
|
|
69
|
-
require_relative "omq/transport/ipc"
|
|
70
6
|
|
|
71
7
|
# Core
|
|
8
|
+
require_relative "omq/version"
|
|
9
|
+
require_relative "omq/constants"
|
|
72
10
|
require_relative "omq/reactor"
|
|
73
11
|
require_relative "omq/options"
|
|
74
12
|
require_relative "omq/routing"
|
|
@@ -86,6 +24,13 @@ require_relative "omq/routing/xsub"
|
|
|
86
24
|
require_relative "omq/routing/push"
|
|
87
25
|
require_relative "omq/routing/pull"
|
|
88
26
|
require_relative "omq/engine"
|
|
27
|
+
|
|
28
|
+
# Transport
|
|
29
|
+
require_relative "omq/transport/inproc"
|
|
30
|
+
require_relative "omq/transport/tcp"
|
|
31
|
+
require_relative "omq/transport/ipc"
|
|
32
|
+
|
|
33
|
+
# Mixins
|
|
89
34
|
require_relative "omq/queue_interface"
|
|
90
35
|
require_relative "omq/readable"
|
|
91
36
|
require_relative "omq/writable"
|
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.24.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -65,6 +65,9 @@ files:
|
|
|
65
65
|
- LICENSE
|
|
66
66
|
- README.md
|
|
67
67
|
- lib/omq.rb
|
|
68
|
+
- lib/omq/channel.rb
|
|
69
|
+
- lib/omq/client_server.rb
|
|
70
|
+
- lib/omq/constants.rb
|
|
68
71
|
- lib/omq/drop_queue.rb
|
|
69
72
|
- lib/omq/engine.rb
|
|
70
73
|
- lib/omq/engine/connection_lifecycle.rb
|
|
@@ -73,37 +76,48 @@ files:
|
|
|
73
76
|
- lib/omq/engine/reconnect.rb
|
|
74
77
|
- lib/omq/engine/recv_pump.rb
|
|
75
78
|
- lib/omq/engine/socket_lifecycle.rb
|
|
76
|
-
- lib/omq/monitor_event.rb
|
|
77
79
|
- lib/omq/options.rb
|
|
78
80
|
- lib/omq/pair.rb
|
|
81
|
+
- lib/omq/peer.rb
|
|
79
82
|
- lib/omq/pub_sub.rb
|
|
80
83
|
- lib/omq/push_pull.rb
|
|
81
84
|
- lib/omq/queue_interface.rb
|
|
85
|
+
- lib/omq/radio_dish.rb
|
|
82
86
|
- lib/omq/reactor.rb
|
|
83
87
|
- lib/omq/readable.rb
|
|
84
88
|
- lib/omq/req_rep.rb
|
|
85
89
|
- lib/omq/router_dealer.rb
|
|
86
90
|
- lib/omq/routing.rb
|
|
91
|
+
- lib/omq/routing/channel.rb
|
|
92
|
+
- lib/omq/routing/client.rb
|
|
87
93
|
- lib/omq/routing/conn_send_pump.rb
|
|
88
94
|
- lib/omq/routing/dealer.rb
|
|
95
|
+
- lib/omq/routing/dish.rb
|
|
89
96
|
- lib/omq/routing/fan_out.rb
|
|
97
|
+
- lib/omq/routing/gather.rb
|
|
90
98
|
- lib/omq/routing/pair.rb
|
|
99
|
+
- lib/omq/routing/peer.rb
|
|
91
100
|
- lib/omq/routing/pub.rb
|
|
92
101
|
- lib/omq/routing/pull.rb
|
|
93
102
|
- lib/omq/routing/push.rb
|
|
103
|
+
- lib/omq/routing/radio.rb
|
|
94
104
|
- lib/omq/routing/rep.rb
|
|
95
105
|
- lib/omq/routing/req.rb
|
|
96
106
|
- lib/omq/routing/round_robin.rb
|
|
97
107
|
- lib/omq/routing/router.rb
|
|
108
|
+
- lib/omq/routing/scatter.rb
|
|
109
|
+
- lib/omq/routing/server.rb
|
|
98
110
|
- lib/omq/routing/sub.rb
|
|
99
111
|
- lib/omq/routing/xpub.rb
|
|
100
112
|
- lib/omq/routing/xsub.rb
|
|
113
|
+
- lib/omq/scatter_gather.rb
|
|
101
114
|
- lib/omq/single_frame.rb
|
|
102
115
|
- lib/omq/socket.rb
|
|
103
116
|
- lib/omq/transport/inproc.rb
|
|
104
|
-
- lib/omq/transport/inproc/
|
|
117
|
+
- lib/omq/transport/inproc/pipe.rb
|
|
105
118
|
- lib/omq/transport/ipc.rb
|
|
106
119
|
- lib/omq/transport/tcp.rb
|
|
120
|
+
- lib/omq/transport/udp.rb
|
|
107
121
|
- lib/omq/version.rb
|
|
108
122
|
- lib/omq/writable.rb
|
|
109
123
|
homepage: https://github.com/zeromq/omq
|
data/lib/omq/monitor_event.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module OMQ
|
|
4
|
-
# Lifecycle event emitted by {Socket#monitor}.
|
|
5
|
-
#
|
|
6
|
-
# @!attribute [r] type
|
|
7
|
-
# @return [Symbol] event type (:listening, :connected, :disconnected, etc.)
|
|
8
|
-
# @!attribute [r] endpoint
|
|
9
|
-
# @return [String, nil] the endpoint involved
|
|
10
|
-
# @!attribute [r] detail
|
|
11
|
-
# @return [Hash, nil] extra context (e.g. { error: }, { interval: }, etc.)
|
|
12
|
-
#
|
|
13
|
-
MonitorEvent = Data.define(:type, :endpoint, :detail) do
|
|
14
|
-
def initialize(type:, endpoint: nil, detail: nil) = super
|
|
15
|
-
end
|
|
16
|
-
end
|