omq-cli 0.8.1 → 0.8.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 +22 -0
- data/lib/omq/cli/base_runner.rb +10 -2
- data/lib/omq/cli/cli_parser.rb +2 -3
- data/lib/omq/cli/formatter.rb +4 -1
- data/lib/omq/cli/parallel_worker.rb +4 -1
- data/lib/omq/cli/pipe.rb +11 -3
- data/lib/omq/cli/pipe_worker.rb +8 -5
- data/lib/omq/cli/version.rb +1 -1
- data/lib/omq/cli.rb +3 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca06571b7529ab16630ce2f769a2320607baf67b87888218ada7a1aa6f05f52a
|
|
4
|
+
data.tar.gz: c46c9b2a8b358ac16d295ea15031da901859c0130295f4508cf3422eac083a24
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bcaa20a52a55171a61098296f0a0a9d8e653bbc6758cf0b21c692c54baa483b3d0d07d96e8c1c9095853984e7c4fe64a2efee60934c193a583892651afa896d8
|
|
7
|
+
data.tar.gz: 93f70eb26ca6e182486fb2280dedf1b780fa084e9d810c5d9eaeeb3842cdcbe968e22b9ec6517ce69d395c095350f59c94aff142c2ce75f9ecc31a925b1ff73b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.2 — 2026-04-08
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **`DecompressError` handling** — decompression failures now raise a proper
|
|
8
|
+
`DecompressError` instead of calling `abort`. In parallel mode (`-P`),
|
|
9
|
+
errors are sent through a dedicated `Ractor::Port` with a consumer thread
|
|
10
|
+
that aborts cleanly (exit code 1, one error message). Previously, `Async do`
|
|
11
|
+
swallowed the exception and the process exited silently.
|
|
12
|
+
- **Pipe memory growth** — pipe sockets now pass `recv_hwm` / `send_hwm` via
|
|
13
|
+
constructor kwargs so the engine captures them before internal queue sizing.
|
|
14
|
+
Previously, setters were called after the engine was initialized and had no
|
|
15
|
+
effect on staging queue capacity.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **`-P N` mandatory argument** — `-P` now requires an explicit worker count.
|
|
20
|
+
Previously, `-Pq` silently consumed `-q` as the argument to `-P`, making
|
|
21
|
+
`-q` (quiet) ineffective.
|
|
22
|
+
- **Pipe default HWM lowered to 16** — reduced from 64 to further bound memory
|
|
23
|
+
with large messages in pipeline stages.
|
|
24
|
+
|
|
3
25
|
## 0.8.1 — 2026-04-08
|
|
4
26
|
|
|
5
27
|
### Fixed
|
data/lib/omq/cli/base_runner.rb
CHANGED
|
@@ -55,10 +55,17 @@ module OMQ
|
|
|
55
55
|
eps = RactorHelpers.preresolve_tcp(config.endpoints)
|
|
56
56
|
output_port, output_thread = RactorHelpers.start_output_consumer
|
|
57
57
|
log_port, log_thread = RactorHelpers.start_log_consumer
|
|
58
|
+
error_port = Ractor::Port.new
|
|
59
|
+
error_thread = Thread.new(error_port) do |p|
|
|
60
|
+
msg = p.receive
|
|
61
|
+
abort "omq: #{msg}" unless msg.equal?(RactorHelpers::SHUTDOWN)
|
|
62
|
+
rescue Ractor::ClosedError
|
|
63
|
+
# port closed, no error
|
|
64
|
+
end
|
|
58
65
|
|
|
59
66
|
workers = config.parallel.times.map do
|
|
60
|
-
::Ractor.new(config, socket_sym, eps, output_port, log_port) do |cfg, sym, e, oport, lport|
|
|
61
|
-
ParallelWorker.new(cfg, sym, e, oport, lport).call
|
|
67
|
+
::Ractor.new(config, socket_sym, eps, output_port, log_port, error_port) do |cfg, sym, e, oport, lport, eport|
|
|
68
|
+
ParallelWorker.new(cfg, sym, e, oport, lport, eport).call
|
|
62
69
|
end
|
|
63
70
|
end
|
|
64
71
|
|
|
@@ -68,6 +75,7 @@ module OMQ
|
|
|
68
75
|
$stderr.write("omq: Ractor error: #{e.cause&.message || e.message}\n")
|
|
69
76
|
end
|
|
70
77
|
ensure
|
|
78
|
+
RactorHelpers.stop_consumer(error_port, error_thread) if error_port
|
|
71
79
|
RactorHelpers.stop_consumer(output_port, output_thread) if output_port
|
|
72
80
|
RactorHelpers.stop_consumer(log_port, log_thread) if log_port
|
|
73
81
|
end
|
data/lib/omq/cli/cli_parser.rb
CHANGED
|
@@ -367,9 +367,8 @@ module OMQ
|
|
|
367
367
|
require "omq" unless defined?(OMQ::VERSION)
|
|
368
368
|
opts[:scripts] << (v == "-" ? :stdin : (v.start_with?("./", "../") ? File.expand_path(v) : v))
|
|
369
369
|
}
|
|
370
|
-
o.on("-P", "--parallel
|
|
371
|
-
|
|
372
|
-
opts[:parallel] = [v || Etc.nprocessors, 16].min
|
|
370
|
+
o.on("-P", "--parallel N", Integer, "Parallel Ractor workers (max 16)") { |v|
|
|
371
|
+
opts[:parallel] = [v, 16].min
|
|
373
372
|
}
|
|
374
373
|
|
|
375
374
|
o.separator "\nCURVE encryption (requires system libsodium):"
|
data/lib/omq/cli/formatter.rb
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module OMQ
|
|
4
4
|
module CLI
|
|
5
|
+
# Raised when Zstandard decompression fails.
|
|
6
|
+
class DecompressError < RuntimeError; end
|
|
7
|
+
|
|
5
8
|
# Handles encoding/decoding messages in the configured format,
|
|
6
9
|
# plus optional Zstandard compression.
|
|
7
10
|
class Formatter
|
|
@@ -96,7 +99,7 @@ module OMQ
|
|
|
96
99
|
def decompress(parts)
|
|
97
100
|
@compress ? parts.map { |p| Zstd.decompress(p) } : parts
|
|
98
101
|
rescue
|
|
99
|
-
|
|
102
|
+
raise DecompressError, "decompression failed (did the sender use --compress?)"
|
|
100
103
|
end
|
|
101
104
|
|
|
102
105
|
|
|
@@ -10,12 +10,13 @@ module OMQ
|
|
|
10
10
|
# - rep (recv-reply with echo/data/eval)
|
|
11
11
|
#
|
|
12
12
|
class ParallelWorker
|
|
13
|
-
def initialize(config, socket_sym, endpoints, output_port, log_port)
|
|
13
|
+
def initialize(config, socket_sym, endpoints, output_port, log_port, error_port)
|
|
14
14
|
@config = config
|
|
15
15
|
@socket_sym = socket_sym
|
|
16
16
|
@endpoints = endpoints
|
|
17
17
|
@output_port = output_port
|
|
18
18
|
@log_port = log_port
|
|
19
|
+
@error_port = error_port
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
|
|
@@ -28,6 +29,8 @@ module OMQ
|
|
|
28
29
|
compile_expr
|
|
29
30
|
run_loop
|
|
30
31
|
run_end_block
|
|
32
|
+
rescue DecompressError => e
|
|
33
|
+
@error_port.send(e.message)
|
|
31
34
|
ensure
|
|
32
35
|
@sock&.close
|
|
33
36
|
end
|
data/lib/omq/cli/pipe.rb
CHANGED
|
@@ -8,7 +8,7 @@ module OMQ
|
|
|
8
8
|
# Default HWM for pipe sockets when the user hasn't set one.
|
|
9
9
|
# Much lower than the socket default (1000) to bound memory
|
|
10
10
|
# with large messages in pipeline stages.
|
|
11
|
-
PIPE_HWM =
|
|
11
|
+
PIPE_HWM = 16
|
|
12
12
|
|
|
13
13
|
# @return [Config] frozen CLI configuration
|
|
14
14
|
attr_reader :config
|
|
@@ -129,9 +129,16 @@ module OMQ
|
|
|
129
129
|
in_eps = RactorHelpers.preresolve_tcp(in_eps)
|
|
130
130
|
out_eps = RactorHelpers.preresolve_tcp(out_eps)
|
|
131
131
|
log_port, log_thread = RactorHelpers.start_log_consumer
|
|
132
|
+
error_port = Ractor::Port.new
|
|
133
|
+
error_thread = Thread.new(error_port) do |p|
|
|
134
|
+
msg = p.receive
|
|
135
|
+
abort "omq: #{msg}" unless msg.equal?(RactorHelpers::SHUTDOWN)
|
|
136
|
+
rescue Ractor::ClosedError
|
|
137
|
+
# port closed, no error
|
|
138
|
+
end
|
|
132
139
|
workers = config.parallel.times.map do
|
|
133
|
-
::Ractor.new(config, in_eps, out_eps, log_port) do |cfg, ins, outs, lport|
|
|
134
|
-
PipeWorker.new(cfg, ins, outs, lport).call
|
|
140
|
+
::Ractor.new(config, in_eps, out_eps, log_port, error_port) do |cfg, ins, outs, lport, eport|
|
|
141
|
+
PipeWorker.new(cfg, ins, outs, lport, eport).call
|
|
135
142
|
end
|
|
136
143
|
end
|
|
137
144
|
workers.each do |w|
|
|
@@ -140,6 +147,7 @@ module OMQ
|
|
|
140
147
|
$stderr.write("omq: Ractor error: #{e.cause&.message || e.message}\n")
|
|
141
148
|
end
|
|
142
149
|
ensure
|
|
150
|
+
RactorHelpers.stop_consumer(error_port, error_thread) if error_port
|
|
143
151
|
RactorHelpers.stop_consumer(log_port, log_thread) if log_port
|
|
144
152
|
end
|
|
145
153
|
|
data/lib/omq/cli/pipe_worker.rb
CHANGED
|
@@ -6,11 +6,12 @@ module OMQ
|
|
|
6
6
|
# Each worker owns its own Async reactor, PULL socket, and PUSH socket.
|
|
7
7
|
#
|
|
8
8
|
class PipeWorker
|
|
9
|
-
def initialize(config, in_eps, out_eps, log_port)
|
|
10
|
-
@config
|
|
11
|
-
@in_eps
|
|
12
|
-
@out_eps
|
|
13
|
-
@log_port
|
|
9
|
+
def initialize(config, in_eps, out_eps, log_port, error_port = nil)
|
|
10
|
+
@config = config
|
|
11
|
+
@in_eps = in_eps
|
|
12
|
+
@out_eps = out_eps
|
|
13
|
+
@log_port = log_port
|
|
14
|
+
@error_port = error_port
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
|
|
@@ -23,6 +24,8 @@ module OMQ
|
|
|
23
24
|
compile_expr
|
|
24
25
|
run_message_loop
|
|
25
26
|
run_end_block
|
|
27
|
+
rescue OMQ::CLI::DecompressError => e
|
|
28
|
+
@error_port&.send(e.message)
|
|
26
29
|
ensure
|
|
27
30
|
@pull&.close
|
|
28
31
|
@push&.close
|
data/lib/omq/cli/version.rb
CHANGED
data/lib/omq/cli.rb
CHANGED
|
@@ -246,6 +246,9 @@ module OMQ
|
|
|
246
246
|
runner_class.new(config)
|
|
247
247
|
end
|
|
248
248
|
runner.call(task)
|
|
249
|
+
rescue DecompressError => e
|
|
250
|
+
$stderr.puts "omq: #{e.message}"
|
|
251
|
+
exit 1
|
|
249
252
|
rescue IO::TimeoutError, Async::TimeoutError
|
|
250
253
|
$stderr.puts "omq: timeout" unless config.quiet
|
|
251
254
|
exit 2
|