omq 0.11.0 → 0.13.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 +143 -0
- data/README.md +3 -1
- data/lib/omq/drop_queue.rb +54 -0
- data/lib/omq/engine/connection_setup.rb +47 -0
- data/lib/omq/engine/heartbeat.rb +40 -0
- data/lib/omq/engine/reconnect.rb +56 -0
- data/lib/omq/engine/recv_pump.rb +76 -0
- data/lib/omq/engine.rb +145 -371
- 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/conn_send_pump.rb +36 -0
- data/lib/omq/routing/dealer.rb +8 -10
- data/lib/omq/routing/fair_queue.rb +144 -0
- data/lib/omq/routing/fair_recv.rb +27 -0
- data/lib/omq/routing/fan_out.rb +116 -63
- data/lib/omq/routing/pair.rb +39 -20
- data/lib/omq/routing/pub.rb +5 -7
- data/lib/omq/routing/pull.rb +5 -4
- data/lib/omq/routing/push.rb +3 -10
- data/lib/omq/routing/rep.rb +31 -51
- data/lib/omq/routing/req.rb +15 -12
- data/lib/omq/routing/round_robin.rb +82 -72
- data/lib/omq/routing/router.rb +23 -48
- data/lib/omq/routing/sub.rb +8 -6
- data/lib/omq/routing/xpub.rb +8 -4
- data/lib/omq/routing/xsub.rb +43 -27
- data/lib/omq/routing.rb +44 -11
- data/lib/omq/socket.rb +46 -5
- data/lib/omq/transport/inproc/direct_pipe.rb +162 -0
- data/lib/omq/transport/inproc.rb +37 -200
- 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 +11 -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/scatter_gather.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module OMQ
|
|
4
|
-
class SCATTER < Socket
|
|
5
|
-
include Writable
|
|
6
|
-
include SingleFrame
|
|
7
|
-
|
|
8
|
-
def initialize(endpoints = nil, linger: 0, send_hwm: nil, send_timeout: nil, backend: nil)
|
|
9
|
-
_init_engine(:SCATTER, linger: linger, send_hwm: send_hwm, send_timeout: send_timeout, backend: backend)
|
|
10
|
-
_attach(endpoints, default: :connect)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
class GATHER < Socket
|
|
15
|
-
include Readable
|
|
16
|
-
include SingleFrame
|
|
17
|
-
|
|
18
|
-
def initialize(endpoints = nil, linger: 0, recv_hwm: nil, recv_timeout: nil, backend: nil)
|
|
19
|
-
_init_engine(:GATHER, linger: linger, recv_hwm: recv_hwm, recv_timeout: recv_timeout, backend: backend)
|
|
20
|
-
_attach(endpoints, default: :bind)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
data/lib/omq/single_frame.rb
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module OMQ
|
|
4
|
-
# Mixin that rejects multipart messages.
|
|
5
|
-
#
|
|
6
|
-
# All draft socket types (CLIENT, SERVER, RADIO, DISH, SCATTER,
|
|
7
|
-
# GATHER, PEER, CHANNEL) require single-frame messages for
|
|
8
|
-
# thread-safe atomic operations.
|
|
9
|
-
#
|
|
10
|
-
module SingleFrame
|
|
11
|
-
def send(message)
|
|
12
|
-
if message.is_a?(Array) && message.size > 1
|
|
13
|
-
raise ArgumentError, "#{self.class} does not support multipart messages"
|
|
14
|
-
end
|
|
15
|
-
super
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
data/lib/omq/transport/tls.rb
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "socket"
|
|
4
|
-
require "uri"
|
|
5
|
-
require "openssl"
|
|
6
|
-
require "io/stream"
|
|
7
|
-
|
|
8
|
-
module OMQ
|
|
9
|
-
module Transport
|
|
10
|
-
# TLS transport — TLS v1.3 on top of TCP.
|
|
11
|
-
#
|
|
12
|
-
# Requires the socket's +tls_context+ to be set to an
|
|
13
|
-
# +OpenSSL::SSL::SSLContext+ before bind or connect.
|
|
14
|
-
#
|
|
15
|
-
module TLS
|
|
16
|
-
TLS_PREFIX = "tls+tcp://"
|
|
17
|
-
|
|
18
|
-
class << self
|
|
19
|
-
# Binds a TLS server.
|
|
20
|
-
#
|
|
21
|
-
# @param endpoint [String] e.g. "tls+tcp://127.0.0.1:5555" or "tls+tcp://*:0"
|
|
22
|
-
# @param engine [Engine]
|
|
23
|
-
# @return [Listener]
|
|
24
|
-
#
|
|
25
|
-
def bind(endpoint, engine)
|
|
26
|
-
ctx = require_context!(engine)
|
|
27
|
-
host, port = parse_endpoint(endpoint)
|
|
28
|
-
host = "0.0.0.0" if host == "*"
|
|
29
|
-
|
|
30
|
-
addrs = Addrinfo.getaddrinfo(host, port, nil, :STREAM, nil, ::Socket::AI_PASSIVE)
|
|
31
|
-
raise ::Socket::ResolutionError, "no addresses for #{host}" if addrs.empty?
|
|
32
|
-
|
|
33
|
-
servers = []
|
|
34
|
-
actual_port = nil
|
|
35
|
-
|
|
36
|
-
addrs.each do |addr|
|
|
37
|
-
server = TCPServer.new(addr.ip_address, actual_port || port)
|
|
38
|
-
actual_port ||= server.local_address.ip_port
|
|
39
|
-
servers << server
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
host_part = host.include?(":") ? "[#{host}]" : host
|
|
43
|
-
resolved = "#{TLS_PREFIX}#{host_part}:#{actual_port}"
|
|
44
|
-
Listener.new(resolved, servers, actual_port, ctx)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Connects to a TLS endpoint.
|
|
48
|
-
#
|
|
49
|
-
# @param endpoint [String] e.g. "tls+tcp://127.0.0.1:5555"
|
|
50
|
-
# @param engine [Engine]
|
|
51
|
-
# @return [void]
|
|
52
|
-
#
|
|
53
|
-
def connect(endpoint, engine)
|
|
54
|
-
ctx = require_context!(engine)
|
|
55
|
-
host, port = parse_endpoint(endpoint)
|
|
56
|
-
tcp_sock = TCPSocket.new(host, port)
|
|
57
|
-
|
|
58
|
-
ssl = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx)
|
|
59
|
-
ssl.sync_close = true
|
|
60
|
-
ssl.hostname = host
|
|
61
|
-
ssl.connect
|
|
62
|
-
|
|
63
|
-
engine.handle_connected(IO::Stream::Buffered.wrap(ssl), endpoint: endpoint)
|
|
64
|
-
rescue
|
|
65
|
-
tcp_sock&.close unless ssl&.sync_close
|
|
66
|
-
raise
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
# Validates and freezes the TLS context from engine options.
|
|
72
|
-
#
|
|
73
|
-
# The context SHOULD have min_version set to TLS1_3_VERSION.
|
|
74
|
-
# We cannot validate this because SSLContext#min_version is
|
|
75
|
-
# write-only in Ruby's OpenSSL binding.
|
|
76
|
-
#
|
|
77
|
-
# @return [OpenSSL::SSL::SSLContext]
|
|
78
|
-
# @raise [ArgumentError] if no context is set
|
|
79
|
-
#
|
|
80
|
-
def require_context!(engine)
|
|
81
|
-
ctx = engine.options.tls_context
|
|
82
|
-
raise ArgumentError, "tls_context must be set for tls+tcp:// endpoints" unless ctx
|
|
83
|
-
ctx.freeze unless ctx.frozen?
|
|
84
|
-
ctx
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Parses a tls+tcp:// endpoint URI into host and port.
|
|
88
|
-
#
|
|
89
|
-
# @param endpoint [String]
|
|
90
|
-
# @return [Array(String, Integer)]
|
|
91
|
-
#
|
|
92
|
-
def parse_endpoint(endpoint)
|
|
93
|
-
uri = URI.parse("http://#{endpoint.delete_prefix(TLS_PREFIX)}")
|
|
94
|
-
[uri.hostname, uri.port]
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# A bound TLS listener.
|
|
99
|
-
#
|
|
100
|
-
class Listener
|
|
101
|
-
# @return [String] resolved endpoint with actual port
|
|
102
|
-
attr_reader :endpoint
|
|
103
|
-
|
|
104
|
-
# @return [Integer] bound port
|
|
105
|
-
attr_reader :port
|
|
106
|
-
|
|
107
|
-
# @return [Array<TCPServer>] bound server sockets
|
|
108
|
-
attr_reader :servers
|
|
109
|
-
|
|
110
|
-
# @return [OpenSSL::SSL::SSLContext]
|
|
111
|
-
attr_reader :ssl_context
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
# @param endpoint [String] resolved endpoint URI
|
|
115
|
-
# @param servers [Array<TCPServer>]
|
|
116
|
-
# @param port [Integer] bound port number
|
|
117
|
-
# @param ssl_context [OpenSSL::SSL::SSLContext]
|
|
118
|
-
#
|
|
119
|
-
def initialize(endpoint, servers, port, ssl_context)
|
|
120
|
-
@endpoint = endpoint
|
|
121
|
-
@servers = servers
|
|
122
|
-
@port = port
|
|
123
|
-
@ssl_context = ssl_context
|
|
124
|
-
@tasks = []
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# Registers accept loop tasks owned by the engine.
|
|
129
|
-
#
|
|
130
|
-
# @param tasks [Array<Async::Task>]
|
|
131
|
-
#
|
|
132
|
-
def accept_tasks=(tasks)
|
|
133
|
-
@tasks = tasks
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
# Stops the listener.
|
|
138
|
-
#
|
|
139
|
-
def stop
|
|
140
|
-
@tasks.each(&:stop)
|
|
141
|
-
@servers.each { |s| s.close rescue nil }
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|