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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fee7d6befc3d75eadd78d241a99e38d8ba09efe5762ae6dab74e9db1eff8eb7
4
- data.tar.gz: 960b9992c93c11d9ac28f910ab815be6a7b7adcf4a3f1e69036306be0283ce50
3
+ metadata.gz: ca06571b7529ab16630ce2f769a2320607baf67b87888218ada7a1aa6f05f52a
4
+ data.tar.gz: c46c9b2a8b358ac16d295ea15031da901859c0130295f4508cf3422eac083a24
5
5
  SHA512:
6
- metadata.gz: 2e12c6048d102048c32aaad64f0b9f321b0f1994adc37132fbd9de836acd6c04fcb6c401424686e65ed6061464f662525e1397c64cee43f03818c7d4dbea9c2b
7
- data.tar.gz: f67ec29b9ebc68f335e29c9ec4e73215f41233fc00c6760bd6fdcac5ee7121826e38aca0c5761b58f9cda78d837651c760553a2d4b64daf2e3105853f1c5661d
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
@@ -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
@@ -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 [N]", Integer, "Parallel Ractor workers for pipe (default: nproc, max 16)") { |v|
371
- require "etc"
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):"
@@ -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
- abort "omq: decompression failed (did the sender use --compress?)"
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 = 64
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
 
@@ -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 = config
11
- @in_eps = in_eps
12
- @out_eps = out_eps
13
- @log_port = 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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OMQ
4
4
  module CLI
5
- VERSION = "0.8.1"
5
+ VERSION = "0.8.2"
6
6
  end
7
7
  end
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
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.8.1
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Wenger