omq-cli 0.7.1 → 0.7.2
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 +11 -0
- data/lib/omq/cli/base_runner.rb +7 -13
- data/lib/omq/cli/pipe.rb +28 -152
- data/lib/omq/cli/pipe_worker.rb +204 -0
- data/lib/omq/cli/version.rb +1 -1
- data/lib/omq/cli.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5af8706d0afd5ad199301ec7b37a47a232c5732a930eada3696a9f60a31aecc4
|
|
4
|
+
data.tar.gz: 6e5b15d9bb2af20181cccbc71d5b4d432938660a8e052d62598c18386ddf2a5d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d35e218e4327b8a0c22c6ce15d9d205f62feffeec2fa2afd21cda6fcef96724645ea76922f0d0dd67099883b2795a0443211bbabf729c4c857e77e1a3b4299b
|
|
7
|
+
data.tar.gz: 34af31e1dc6605c6b90bc7dcb3f519755d13a12e71f4417de7a5d07f71617610fc6d728f57f1be5f51bda6923d49fc1a6fc8cb1cbc6234d31c37ad392b8c3452
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.2 — 2026-04-07
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- **Cleaned up pipe.rb** — removed unused `@fmt` formatters, dead `log` method,
|
|
8
|
+
and `with_timeout` wrapper. Moved `preresolve_tcp` and `start_log_consumer` to
|
|
9
|
+
`PipeWorker` class methods.
|
|
10
|
+
- **Guard `with_timeout(nil)`** — `Fiber.scheduler.with_timeout(nil)` fires
|
|
11
|
+
immediately in Async; peer-wait and pipe sequential mode now skip the timeout
|
|
12
|
+
wrapper when `config.timeout` is nil.
|
|
13
|
+
|
|
3
14
|
## 0.7.1 — 2026-04-07
|
|
4
15
|
|
|
5
16
|
### Fixed
|
data/lib/omq/cli/base_runner.rb
CHANGED
|
@@ -107,12 +107,18 @@ module OMQ
|
|
|
107
107
|
|
|
108
108
|
|
|
109
109
|
def wait_for_peer
|
|
110
|
-
|
|
110
|
+
wait_body = proc do
|
|
111
111
|
@sock.peer_connected.wait
|
|
112
112
|
log "Peer connected"
|
|
113
113
|
wait_for_subscriber
|
|
114
114
|
apply_grace_period
|
|
115
115
|
end
|
|
116
|
+
|
|
117
|
+
if config.timeout
|
|
118
|
+
Fiber.scheduler.with_timeout(config.timeout, &wait_body)
|
|
119
|
+
else
|
|
120
|
+
wait_body.call
|
|
121
|
+
end
|
|
116
122
|
end
|
|
117
123
|
|
|
118
124
|
|
|
@@ -133,18 +139,6 @@ module OMQ
|
|
|
133
139
|
end
|
|
134
140
|
|
|
135
141
|
|
|
136
|
-
# ── Timeout helper ──────────────────────────────────────────────
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def with_timeout(seconds)
|
|
140
|
-
if seconds
|
|
141
|
-
Async::Task.current.with_timeout(seconds) { yield }
|
|
142
|
-
else
|
|
143
|
-
yield
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
|
|
148
142
|
# ── Socket setup ────────────────────────────────────────────────
|
|
149
143
|
|
|
150
144
|
|
data/lib/omq/cli/pipe.rb
CHANGED
|
@@ -11,8 +11,7 @@ module OMQ
|
|
|
11
11
|
|
|
12
12
|
# @param config [Config] frozen CLI configuration
|
|
13
13
|
def initialize(config)
|
|
14
|
-
@config
|
|
15
|
-
@fmt = Formatter.new(config.format, compress: config.compress)
|
|
14
|
+
@config = config
|
|
16
15
|
@fmt_in = Formatter.new(config.format, compress: config.compress_in || config.compress)
|
|
17
16
|
@fmt_out = Formatter.new(config.format, compress: config.compress_out || config.compress)
|
|
18
17
|
end
|
|
@@ -43,30 +42,27 @@ module OMQ
|
|
|
43
42
|
end
|
|
44
43
|
|
|
45
44
|
|
|
46
|
-
def attach_endpoints(sock, endpoints)
|
|
47
|
-
SocketSetup.attach_endpoints(sock, endpoints, verbose: config.verbose >= 1)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
|
|
51
45
|
# ── Sequential ───────────────────────────────────────────────────
|
|
52
46
|
|
|
53
47
|
|
|
54
48
|
def run_sequential(task)
|
|
55
49
|
in_eps, out_eps = resolve_endpoints
|
|
56
|
-
@pull, @push = build_pull_push(
|
|
57
|
-
{ linger: config.linger, recv_timeout: config.timeout },
|
|
58
|
-
{ linger: config.linger, send_timeout: config.timeout },
|
|
59
|
-
in_eps, out_eps
|
|
60
|
-
)
|
|
50
|
+
@pull, @push = build_pull_push(in_eps, out_eps)
|
|
61
51
|
compile_expr
|
|
62
52
|
@sock = @pull # for eval instance_exec
|
|
63
53
|
start_event_monitors if config.verbose >= 2
|
|
64
|
-
|
|
54
|
+
wait_body = proc do
|
|
65
55
|
Barrier do |barrier|
|
|
66
56
|
barrier.async(annotation: "wait push peer") { @push.peer_connected.wait }
|
|
67
57
|
barrier.async(annotation: "wait pull peer") { @pull.peer_connected.wait }
|
|
68
58
|
end
|
|
69
59
|
end
|
|
60
|
+
|
|
61
|
+
if config.timeout
|
|
62
|
+
Fiber.scheduler.with_timeout(config.timeout, &wait_body)
|
|
63
|
+
else
|
|
64
|
+
wait_body.call
|
|
65
|
+
end
|
|
70
66
|
setup_sequential_transient(task)
|
|
71
67
|
@sock.instance_exec(&@recv_begin_proc) if @recv_begin_proc
|
|
72
68
|
sequential_message_loop
|
|
@@ -87,13 +83,13 @@ module OMQ
|
|
|
87
83
|
end
|
|
88
84
|
|
|
89
85
|
|
|
90
|
-
def build_pull_push(
|
|
91
|
-
pull = OMQ::PULL.new(
|
|
92
|
-
push = OMQ::PUSH.new(
|
|
86
|
+
def build_pull_push(in_eps, out_eps)
|
|
87
|
+
pull = OMQ::PULL.new(linger: config.linger, recv_timeout: config.timeout)
|
|
88
|
+
push = OMQ::PUSH.new(linger: config.linger, send_timeout: config.timeout)
|
|
93
89
|
apply_socket_options(pull)
|
|
94
90
|
apply_socket_options(push)
|
|
95
|
-
attach_endpoints(pull, in_eps)
|
|
96
|
-
attach_endpoints(push, out_eps)
|
|
91
|
+
SocketSetup.attach_endpoints(pull, in_eps, verbose: config.verbose >= 1)
|
|
92
|
+
SocketSetup.attach_endpoints(push, out_eps, verbose: config.verbose >= 1)
|
|
97
93
|
[pull, push]
|
|
98
94
|
end
|
|
99
95
|
|
|
@@ -117,8 +113,7 @@ module OMQ
|
|
|
117
113
|
parts = @fmt_in.decompress(parts)
|
|
118
114
|
parts = eval_recv_expr(parts)
|
|
119
115
|
if parts && !parts.empty?
|
|
120
|
-
|
|
121
|
-
@push.send(out)
|
|
116
|
+
@push.send(@fmt_out.compress(parts))
|
|
122
117
|
end
|
|
123
118
|
i += 1
|
|
124
119
|
break if n && n > 0 && i >= n
|
|
@@ -132,143 +127,26 @@ module OMQ
|
|
|
132
127
|
def run_parallel(task)
|
|
133
128
|
OMQ.freeze_for_ractors!
|
|
134
129
|
in_eps, out_eps = resolve_endpoints
|
|
135
|
-
in_eps = preresolve_tcp(in_eps)
|
|
136
|
-
out_eps = preresolve_tcp(out_eps)
|
|
137
|
-
|
|
130
|
+
in_eps = PipeWorker.preresolve_tcp(in_eps)
|
|
131
|
+
out_eps = PipeWorker.preresolve_tcp(out_eps)
|
|
132
|
+
log_port, log_thread = PipeWorker.start_log_consumer
|
|
133
|
+
workers = config.parallel.times.map do
|
|
134
|
+
::Ractor.new(config, in_eps, out_eps, log_port) do |cfg, ins, outs, lport|
|
|
135
|
+
PipeWorker.new(cfg, ins, outs, lport).call
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
138
|
workers.each do |w|
|
|
139
139
|
w.join
|
|
140
140
|
rescue ::Ractor::RemoteError => e
|
|
141
141
|
$stderr.write("omq: Ractor error: #{e.cause&.message || e.message}\n")
|
|
142
142
|
end
|
|
143
|
+
ensure
|
|
144
|
+
log_port.close
|
|
145
|
+
log_thread.join
|
|
143
146
|
end
|
|
144
147
|
|
|
145
148
|
|
|
146
|
-
|
|
147
|
-
config.parallel.times.map do
|
|
148
|
-
::Ractor.new(config, in_eps, out_eps) do |cfg, ins, outs|
|
|
149
|
-
Async do
|
|
150
|
-
pull = OMQ::PULL.new(linger: cfg.linger)
|
|
151
|
-
push = OMQ::PUSH.new(linger: cfg.linger)
|
|
152
|
-
pull.recv_timeout = cfg.timeout if cfg.timeout
|
|
153
|
-
push.send_timeout = cfg.timeout if cfg.timeout
|
|
154
|
-
pull.reconnect_interval = cfg.reconnect_ivl if cfg.reconnect_ivl
|
|
155
|
-
push.reconnect_interval = cfg.reconnect_ivl if cfg.reconnect_ivl
|
|
156
|
-
pull.heartbeat_interval = cfg.heartbeat_ivl if cfg.heartbeat_ivl
|
|
157
|
-
push.heartbeat_interval = cfg.heartbeat_ivl if cfg.heartbeat_ivl
|
|
158
|
-
pull.send_hwm = cfg.send_hwm if cfg.send_hwm
|
|
159
|
-
pull.recv_hwm = cfg.recv_hwm if cfg.recv_hwm
|
|
160
|
-
push.send_hwm = cfg.send_hwm if cfg.send_hwm
|
|
161
|
-
push.recv_hwm = cfg.recv_hwm if cfg.recv_hwm
|
|
162
|
-
pull.sndbuf = cfg.sndbuf if cfg.sndbuf
|
|
163
|
-
pull.rcvbuf = cfg.rcvbuf if cfg.rcvbuf
|
|
164
|
-
push.sndbuf = cfg.sndbuf if cfg.sndbuf
|
|
165
|
-
push.rcvbuf = cfg.rcvbuf if cfg.rcvbuf
|
|
166
|
-
|
|
167
|
-
OMQ::CLI::SocketSetup.attach_endpoints(pull, ins, verbose: cfg.verbose >= 1)
|
|
168
|
-
OMQ::CLI::SocketSetup.attach_endpoints(push, outs, verbose: cfg.verbose >= 1)
|
|
169
|
-
|
|
170
|
-
Barrier do |barrier|
|
|
171
|
-
barrier.async { pull.peer_connected.wait }
|
|
172
|
-
barrier.async { push.peer_connected.wait }
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
begin_proc, end_proc, eval_proc =
|
|
176
|
-
OMQ::CLI::ExpressionEvaluator.compile_inside_ractor(cfg.recv_expr)
|
|
177
|
-
|
|
178
|
-
fmt_in = OMQ::CLI::Formatter.new(cfg.format, compress: cfg.compress_in || cfg.compress)
|
|
179
|
-
fmt_out = OMQ::CLI::Formatter.new(cfg.format, compress: cfg.compress_out || cfg.compress)
|
|
180
|
-
|
|
181
|
-
_ctx = Object.new
|
|
182
|
-
_ctx.instance_exec(&begin_proc) if begin_proc
|
|
183
|
-
|
|
184
|
-
n_count = cfg.count
|
|
185
|
-
begin
|
|
186
|
-
if eval_proc
|
|
187
|
-
if n_count && n_count > 0
|
|
188
|
-
n_count.times do
|
|
189
|
-
parts = pull.receive
|
|
190
|
-
break if parts.nil?
|
|
191
|
-
parts = OMQ::CLI::ExpressionEvaluator.normalize_result(
|
|
192
|
-
_ctx.instance_exec(fmt_in.decompress(parts), &eval_proc)
|
|
193
|
-
)
|
|
194
|
-
next if parts.nil?
|
|
195
|
-
push << fmt_out.compress(parts) unless parts.empty?
|
|
196
|
-
end
|
|
197
|
-
else
|
|
198
|
-
loop do
|
|
199
|
-
parts = pull.receive
|
|
200
|
-
break if parts.nil?
|
|
201
|
-
parts = OMQ::CLI::ExpressionEvaluator.normalize_result(
|
|
202
|
-
_ctx.instance_exec(fmt_in.decompress(parts), &eval_proc)
|
|
203
|
-
)
|
|
204
|
-
next if parts.nil?
|
|
205
|
-
push << fmt_out.compress(parts) unless parts.empty?
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
else
|
|
209
|
-
if n_count && n_count > 0
|
|
210
|
-
n_count.times do
|
|
211
|
-
parts = pull.receive
|
|
212
|
-
break if parts.nil?
|
|
213
|
-
push << fmt_out.compress(fmt_in.decompress(parts))
|
|
214
|
-
end
|
|
215
|
-
else
|
|
216
|
-
loop do
|
|
217
|
-
parts = pull.receive
|
|
218
|
-
break if parts.nil?
|
|
219
|
-
push << fmt_out.compress(fmt_in.decompress(parts))
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
rescue IO::TimeoutError, Async::TimeoutError
|
|
224
|
-
# recv timed out — fall through to END block
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
if end_proc
|
|
228
|
-
out = OMQ::CLI::ExpressionEvaluator.normalize_result(
|
|
229
|
-
_ctx.instance_exec(&end_proc)
|
|
230
|
-
)
|
|
231
|
-
push << fmt_out.compress(out) if out && !out.empty?
|
|
232
|
-
end
|
|
233
|
-
ensure
|
|
234
|
-
pull&.close
|
|
235
|
-
push&.close
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
end
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
# ── Shared helpers ────────────────────────────────────────────────
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
# Resolves TCP hostnames to IP addresses so Ractors don't touch
|
|
246
|
-
# Resolv::DefaultResolver (which is not shareable).
|
|
247
|
-
#
|
|
248
|
-
def preresolve_tcp(endpoints)
|
|
249
|
-
endpoints.flat_map do |ep|
|
|
250
|
-
url = ep.url
|
|
251
|
-
if url.start_with?("tcp://")
|
|
252
|
-
host, port = OMQ::Transport::TCP.parse_endpoint(url)
|
|
253
|
-
Addrinfo.getaddrinfo(host, port, nil, :STREAM).map do |addr|
|
|
254
|
-
ip = addr.ip_address
|
|
255
|
-
ip = "[#{ip}]" if ip.include?(":")
|
|
256
|
-
Endpoint.new("tcp://#{ip}:#{addr.ip_port}", ep.bind?)
|
|
257
|
-
end
|
|
258
|
-
else
|
|
259
|
-
ep
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
def with_timeout(seconds)
|
|
266
|
-
if seconds
|
|
267
|
-
Async::Task.current.with_timeout(seconds) { yield }
|
|
268
|
-
else
|
|
269
|
-
yield
|
|
270
|
-
end
|
|
271
|
-
end
|
|
149
|
+
# ── Expression eval ──────────────────────────────────────────────
|
|
272
150
|
|
|
273
151
|
|
|
274
152
|
def compile_expr
|
|
@@ -285,9 +163,7 @@ module OMQ
|
|
|
285
163
|
end
|
|
286
164
|
|
|
287
165
|
|
|
288
|
-
|
|
289
|
-
$stderr.write("#{msg}\n") if config.verbose >= 1
|
|
290
|
-
end
|
|
166
|
+
# ── Event monitoring ─────────────────────────────────────────────
|
|
291
167
|
|
|
292
168
|
|
|
293
169
|
def start_event_monitors
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OMQ
|
|
4
|
+
module CLI
|
|
5
|
+
# Worker that runs inside a Ractor for pipe -P parallel mode.
|
|
6
|
+
# Each worker owns its own Async reactor, PULL socket, and PUSH socket.
|
|
7
|
+
#
|
|
8
|
+
class PipeWorker
|
|
9
|
+
# Starts a Ractor::Port and a consumer thread that drains log
|
|
10
|
+
# messages to stderr sequentially. Returns [port, thread].
|
|
11
|
+
#
|
|
12
|
+
def self.start_log_consumer
|
|
13
|
+
port = Ractor::Port.new
|
|
14
|
+
thread = Thread.new(port) do |p|
|
|
15
|
+
loop do
|
|
16
|
+
$stderr.write("#{p.receive}\n")
|
|
17
|
+
rescue Ractor::ClosedError
|
|
18
|
+
break
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
[port, thread]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Resolves TCP hostnames to IP addresses so Ractors don't touch
|
|
26
|
+
# Resolv::DefaultResolver (which is not shareable).
|
|
27
|
+
#
|
|
28
|
+
def self.preresolve_tcp(endpoints)
|
|
29
|
+
endpoints.flat_map do |ep|
|
|
30
|
+
url = ep.url
|
|
31
|
+
if url.start_with?("tcp://")
|
|
32
|
+
host, port = OMQ::Transport::TCP.parse_endpoint(url)
|
|
33
|
+
Addrinfo.getaddrinfo(host, port, nil, :STREAM).map do |addr|
|
|
34
|
+
ip = addr.ip_address
|
|
35
|
+
ip = "[#{ip}]" if ip.include?(":")
|
|
36
|
+
Endpoint.new("tcp://#{ip}:#{addr.ip_port}", ep.bind?)
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
ep
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def initialize(config, in_eps, out_eps, log_port)
|
|
46
|
+
@config = config
|
|
47
|
+
@in_eps = in_eps
|
|
48
|
+
@out_eps = out_eps
|
|
49
|
+
@log_port = log_port
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def call
|
|
54
|
+
Async do
|
|
55
|
+
setup_sockets
|
|
56
|
+
log_endpoints if @config.verbose >= 1
|
|
57
|
+
start_monitors if @config.verbose >= 2
|
|
58
|
+
wait_for_peers
|
|
59
|
+
compile_expr
|
|
60
|
+
run_message_loop
|
|
61
|
+
run_end_block
|
|
62
|
+
ensure
|
|
63
|
+
@pull&.close
|
|
64
|
+
@push&.close
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def setup_sockets
|
|
73
|
+
@pull = OMQ::PULL.new(linger: @config.linger)
|
|
74
|
+
@push = OMQ::PUSH.new(linger: @config.linger)
|
|
75
|
+
@pull.recv_timeout = @config.timeout if @config.timeout
|
|
76
|
+
@push.send_timeout = @config.timeout if @config.timeout
|
|
77
|
+
apply_socket_options(@pull)
|
|
78
|
+
apply_socket_options(@push)
|
|
79
|
+
OMQ::CLI::SocketSetup.attach_endpoints(@pull, @in_eps, verbose: false)
|
|
80
|
+
OMQ::CLI::SocketSetup.attach_endpoints(@push, @out_eps, verbose: false)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def apply_socket_options(sock)
|
|
85
|
+
sock.reconnect_interval = @config.reconnect_ivl if @config.reconnect_ivl
|
|
86
|
+
sock.heartbeat_interval = @config.heartbeat_ivl if @config.heartbeat_ivl
|
|
87
|
+
sock.send_hwm = @config.send_hwm if @config.send_hwm
|
|
88
|
+
sock.recv_hwm = @config.recv_hwm if @config.recv_hwm
|
|
89
|
+
sock.sndbuf = @config.sndbuf if @config.sndbuf
|
|
90
|
+
sock.rcvbuf = @config.rcvbuf if @config.rcvbuf
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def log_endpoints
|
|
95
|
+
@in_eps.each { |ep| @log_port.send(ep.bind? ? "Bound to #{ep.url}" : "Connecting to #{ep.url}") }
|
|
96
|
+
@out_eps.each { |ep| @log_port.send(ep.bind? ? "Bound to #{ep.url}" : "Connecting to #{ep.url}") }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def start_monitors
|
|
101
|
+
trace = @config.verbose >= 3
|
|
102
|
+
[@pull, @push].each do |sock|
|
|
103
|
+
sock.monitor(verbose: trace) do |event|
|
|
104
|
+
@log_port.send(format_event(event))
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def format_event(event)
|
|
111
|
+
case event.type
|
|
112
|
+
when :message_sent
|
|
113
|
+
"omq: >> #{msg_preview(event.detail[:parts])}"
|
|
114
|
+
when :message_received
|
|
115
|
+
"omq: << #{msg_preview(event.detail[:parts])}"
|
|
116
|
+
else
|
|
117
|
+
ep = event.endpoint ? " #{event.endpoint}" : ""
|
|
118
|
+
detail = event.detail ? " #{event.detail}" : ""
|
|
119
|
+
"omq: #{event.type}#{ep}#{detail}"
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def msg_preview(parts)
|
|
125
|
+
parts.map { |p|
|
|
126
|
+
bytes = p.b
|
|
127
|
+
preview = bytes[0, 10].gsub(/[^[:print:]]/, ".")
|
|
128
|
+
bytes.bytesize > 10 ? "#{preview}... (#{bytes.bytesize}B)" : preview
|
|
129
|
+
}.join(" | ")
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def wait_for_peers
|
|
134
|
+
Barrier do |barrier|
|
|
135
|
+
barrier.async { @pull.peer_connected.wait }
|
|
136
|
+
barrier.async { @push.peer_connected.wait }
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def compile_expr
|
|
142
|
+
@begin_proc, @end_proc, @eval_proc =
|
|
143
|
+
OMQ::CLI::ExpressionEvaluator.compile_inside_ractor(@config.recv_expr)
|
|
144
|
+
@fmt_in = OMQ::CLI::Formatter.new(@config.format, compress: @config.compress_in || @config.compress)
|
|
145
|
+
@fmt_out = OMQ::CLI::Formatter.new(@config.format, compress: @config.compress_out || @config.compress)
|
|
146
|
+
@ctx = Object.new
|
|
147
|
+
@ctx.instance_exec(&@begin_proc) if @begin_proc
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def run_message_loop
|
|
152
|
+
n = @config.count
|
|
153
|
+
if @eval_proc
|
|
154
|
+
if n && n > 0
|
|
155
|
+
n.times do
|
|
156
|
+
parts = @pull.receive
|
|
157
|
+
break if parts.nil?
|
|
158
|
+
parts = OMQ::CLI::ExpressionEvaluator.normalize_result(
|
|
159
|
+
@ctx.instance_exec(@fmt_in.decompress(parts), &@eval_proc)
|
|
160
|
+
)
|
|
161
|
+
next if parts.nil?
|
|
162
|
+
@push << @fmt_out.compress(parts) unless parts.empty?
|
|
163
|
+
end
|
|
164
|
+
else
|
|
165
|
+
loop do
|
|
166
|
+
parts = @pull.receive
|
|
167
|
+
break if parts.nil?
|
|
168
|
+
parts = OMQ::CLI::ExpressionEvaluator.normalize_result(
|
|
169
|
+
@ctx.instance_exec(@fmt_in.decompress(parts), &@eval_proc)
|
|
170
|
+
)
|
|
171
|
+
next if parts.nil?
|
|
172
|
+
@push << @fmt_out.compress(parts) unless parts.empty?
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
else
|
|
176
|
+
if n && n > 0
|
|
177
|
+
n.times do
|
|
178
|
+
parts = @pull.receive
|
|
179
|
+
break if parts.nil?
|
|
180
|
+
@push << @fmt_out.compress(@fmt_in.decompress(parts))
|
|
181
|
+
end
|
|
182
|
+
else
|
|
183
|
+
loop do
|
|
184
|
+
parts = @pull.receive
|
|
185
|
+
break if parts.nil?
|
|
186
|
+
@push << @fmt_out.compress(@fmt_in.decompress(parts))
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
rescue IO::TimeoutError, Async::TimeoutError
|
|
191
|
+
# recv timed out — fall through to END block
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def run_end_block
|
|
196
|
+
return unless @end_proc
|
|
197
|
+
out = OMQ::CLI::ExpressionEvaluator.normalize_result(
|
|
198
|
+
@ctx.instance_exec(&@end_proc)
|
|
199
|
+
)
|
|
200
|
+
@push << @fmt_out.compress(out) if out && !out.empty?
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
data/lib/omq/cli/version.rb
CHANGED
data/lib/omq/cli.rb
CHANGED
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.7.
|
|
4
|
+
version: 0.7.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -166,6 +166,7 @@ files:
|
|
|
166
166
|
- lib/omq/cli/formatter.rb
|
|
167
167
|
- lib/omq/cli/pair.rb
|
|
168
168
|
- lib/omq/cli/pipe.rb
|
|
169
|
+
- lib/omq/cli/pipe_worker.rb
|
|
169
170
|
- lib/omq/cli/pub_sub.rb
|
|
170
171
|
- lib/omq/cli/push_pull.rb
|
|
171
172
|
- lib/omq/cli/radio_dish.rb
|