omq-cli 0.7.1 → 0.8.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 +41 -0
- data/lib/omq/cli/base_runner.rb +61 -41
- data/lib/omq/cli/cli_parser.rb +57 -52
- data/lib/omq/cli/formatter.rb +16 -0
- data/lib/omq/cli/parallel_worker.rb +191 -0
- data/lib/omq/cli/pipe.rb +52 -172
- data/lib/omq/cli/pipe_worker.rb +149 -0
- data/lib/omq/cli/push_pull.rb +8 -0
- data/lib/omq/cli/ractor_helpers.rb +81 -0
- data/lib/omq/cli/req_rep.rb +5 -0
- data/lib/omq/cli/scatter_gather.rb +8 -0
- data/lib/omq/cli/socket_setup.rb +21 -14
- data/lib/omq/cli/transient_monitor.rb +1 -1
- data/lib/omq/cli/version.rb +1 -1
- data/lib/omq/cli.rb +5 -1
- metadata +4 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OMQ
|
|
4
|
+
module CLI
|
|
5
|
+
# Shared Ractor infrastructure for parallel worker modes.
|
|
6
|
+
module RactorHelpers
|
|
7
|
+
# Sentinel value sent through ports to signal consumer threads to exit.
|
|
8
|
+
# Port#close does not unblock a waiting #receive, so we must send an
|
|
9
|
+
# explicit shutdown marker.
|
|
10
|
+
SHUTDOWN = :__omq_shutdown__
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Resolves TCP hostnames to IP addresses so Ractors don't touch
|
|
14
|
+
# Resolv::DefaultResolver (which is not shareable).
|
|
15
|
+
#
|
|
16
|
+
def self.preresolve_tcp(endpoints)
|
|
17
|
+
endpoints.flat_map do |ep|
|
|
18
|
+
url = ep.url
|
|
19
|
+
if url.start_with?("tcp://")
|
|
20
|
+
host, port = OMQ::Transport::TCP.parse_endpoint(url)
|
|
21
|
+
Addrinfo.getaddrinfo(host, port, nil, :STREAM).map do |addr|
|
|
22
|
+
ip = addr.ip_address
|
|
23
|
+
ip = "[#{ip}]" if ip.include?(":")
|
|
24
|
+
Endpoint.new("tcp://#{ip}:#{addr.ip_port}", ep.bind?)
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
ep
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Starts a Ractor::Port and a consumer thread that drains log
|
|
34
|
+
# messages to stderr sequentially. Returns [port, thread].
|
|
35
|
+
# Send SHUTDOWN through the port to stop the consumer.
|
|
36
|
+
#
|
|
37
|
+
def self.start_log_consumer
|
|
38
|
+
port = Ractor::Port.new
|
|
39
|
+
thread = Thread.new(port) do |p|
|
|
40
|
+
loop do
|
|
41
|
+
msg = p.receive
|
|
42
|
+
break if msg.equal?(SHUTDOWN)
|
|
43
|
+
$stderr.write("#{msg}\n")
|
|
44
|
+
rescue Ractor::ClosedError
|
|
45
|
+
break
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
[port, thread]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# Starts a Ractor::Port and a consumer thread that drains
|
|
53
|
+
# formatted output to stdout sequentially. Returns [port, thread].
|
|
54
|
+
# Send SHUTDOWN through the port to stop the consumer.
|
|
55
|
+
#
|
|
56
|
+
def self.start_output_consumer
|
|
57
|
+
port = Ractor::Port.new
|
|
58
|
+
thread = Thread.new(port) do |p|
|
|
59
|
+
loop do
|
|
60
|
+
msg = p.receive
|
|
61
|
+
break if msg.equal?(SHUTDOWN)
|
|
62
|
+
$stdout.write(msg)
|
|
63
|
+
rescue Ractor::ClosedError
|
|
64
|
+
break
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
[port, thread]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# Sends the shutdown sentinel and joins the consumer thread.
|
|
72
|
+
#
|
|
73
|
+
def self.stop_consumer(port, thread)
|
|
74
|
+
port.send(SHUTDOWN)
|
|
75
|
+
thread.join
|
|
76
|
+
rescue Ractor::ClosedError
|
|
77
|
+
thread.join(1)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
data/lib/omq/cli/req_rep.rb
CHANGED
|
@@ -10,6 +10,14 @@ module OMQ
|
|
|
10
10
|
|
|
11
11
|
# Runner for GATHER sockets (draft; fan-in receive).
|
|
12
12
|
class GatherRunner < BaseRunner
|
|
13
|
+
def call(task)
|
|
14
|
+
config.parallel ? run_parallel_workers(:GATHER) : super
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
|
|
13
21
|
def run_loop(task) = run_recv_logic
|
|
14
22
|
end
|
|
15
23
|
end
|
data/lib/omq/cli/socket_setup.rb
CHANGED
|
@@ -6,23 +6,30 @@ module OMQ
|
|
|
6
6
|
# All methods are module-level so callers compose rather than inherit.
|
|
7
7
|
#
|
|
8
8
|
module SocketSetup
|
|
9
|
+
# Apply common socket options from +config+ to +sock+.
|
|
10
|
+
#
|
|
11
|
+
def self.apply_options(sock, config)
|
|
12
|
+
sock.linger = config.linger
|
|
13
|
+
sock.recv_timeout = config.timeout if config.timeout
|
|
14
|
+
sock.send_timeout = config.timeout if config.timeout
|
|
15
|
+
sock.reconnect_interval = config.reconnect_ivl if config.reconnect_ivl
|
|
16
|
+
sock.heartbeat_interval = config.heartbeat_ivl if config.heartbeat_ivl
|
|
17
|
+
sock.send_hwm = config.send_hwm if config.send_hwm
|
|
18
|
+
sock.recv_hwm = config.recv_hwm if config.recv_hwm
|
|
19
|
+
sock.sndbuf = config.sndbuf if config.sndbuf
|
|
20
|
+
sock.rcvbuf = config.rcvbuf if config.rcvbuf
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
9
24
|
# Create and fully configure a socket from +klass+ and +config+.
|
|
10
25
|
#
|
|
11
26
|
def self.build(klass, config)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
sock
|
|
15
|
-
sock.
|
|
16
|
-
sock.
|
|
17
|
-
sock.
|
|
18
|
-
sock.send_hwm = config.send_hwm if config.send_hwm
|
|
19
|
-
sock.recv_hwm = config.recv_hwm if config.recv_hwm
|
|
20
|
-
sock.sndbuf = config.sndbuf if config.sndbuf
|
|
21
|
-
sock.rcvbuf = config.rcvbuf if config.rcvbuf
|
|
22
|
-
sock.reconnect_interval = config.reconnect_ivl if config.reconnect_ivl
|
|
23
|
-
sock.heartbeat_interval = config.heartbeat_ivl if config.heartbeat_ivl
|
|
24
|
-
sock.identity = config.identity if config.identity
|
|
25
|
-
sock.router_mandatory = true if config.type_name == "router"
|
|
27
|
+
sock = klass.new
|
|
28
|
+
sock.conflate = true if config.conflate && %w[pub radio].include?(config.type_name)
|
|
29
|
+
apply_options(sock, config)
|
|
30
|
+
sock.max_message_size = config.recv_maxsz if config.recv_maxsz
|
|
31
|
+
sock.identity = config.identity if config.identity
|
|
32
|
+
sock.router_mandatory = true if config.type_name == "router"
|
|
26
33
|
sock
|
|
27
34
|
end
|
|
28
35
|
|
data/lib/omq/cli/version.rb
CHANGED
data/lib/omq/cli.rb
CHANGED
|
@@ -18,6 +18,9 @@ require_relative "cli/req_rep"
|
|
|
18
18
|
require_relative "cli/pair"
|
|
19
19
|
require_relative "cli/router_dealer"
|
|
20
20
|
require_relative "cli/client_server"
|
|
21
|
+
require_relative "cli/ractor_helpers"
|
|
22
|
+
require_relative "cli/parallel_worker"
|
|
23
|
+
require_relative "cli/pipe_worker"
|
|
21
24
|
require_relative "cli/pipe"
|
|
22
25
|
|
|
23
26
|
module OMQ
|
|
@@ -168,7 +171,7 @@ module OMQ
|
|
|
168
171
|
abort "CURVE requires libsodium. Install it:\n" \
|
|
169
172
|
" apt install libsodium-dev # Debian/Ubuntu\n" \
|
|
170
173
|
" brew install libsodium # macOS\n" \
|
|
171
|
-
"Or use nuckle (pure Ruby, DANGEROUS
|
|
174
|
+
"Or use nuckle (pure Ruby, DANGEROUS -- not audited):\n" \
|
|
172
175
|
" --crypto nuckle"
|
|
173
176
|
end
|
|
174
177
|
else
|
|
@@ -220,6 +223,7 @@ module OMQ
|
|
|
220
223
|
end
|
|
221
224
|
|
|
222
225
|
if config.type_name.nil?
|
|
226
|
+
Process.setproctitle("omq script")
|
|
223
227
|
Object.include(OMQ) unless Object.include?(OMQ)
|
|
224
228
|
Async annotation: 'omq' do
|
|
225
229
|
Async::Debug.serve(endpoint: debug_ep) if debug_ep
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omq-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -165,9 +165,12 @@ files:
|
|
|
165
165
|
- lib/omq/cli/expression_evaluator.rb
|
|
166
166
|
- lib/omq/cli/formatter.rb
|
|
167
167
|
- lib/omq/cli/pair.rb
|
|
168
|
+
- lib/omq/cli/parallel_worker.rb
|
|
168
169
|
- lib/omq/cli/pipe.rb
|
|
170
|
+
- lib/omq/cli/pipe_worker.rb
|
|
169
171
|
- lib/omq/cli/pub_sub.rb
|
|
170
172
|
- lib/omq/cli/push_pull.rb
|
|
173
|
+
- lib/omq/cli/ractor_helpers.rb
|
|
171
174
|
- lib/omq/cli/radio_dish.rb
|
|
172
175
|
- lib/omq/cli/req_rep.rb
|
|
173
176
|
- lib/omq/cli/router_dealer.rb
|