omq-cli 0.5.4 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c1b5dcd4986d66825e3111c70c7fdafacc726e0561974b134942365bc91513a
4
- data.tar.gz: df996f5b87e3edbb171e4cbfc3ecdc64d6b6bd05d7e3d44dcab90d08b903ea58
3
+ metadata.gz: 7e7461f1ed5fa59b4d82797959a2cfb80f91c74102a0915a7363eed6234ac98e
4
+ data.tar.gz: 1c1af50a6c3cf4f110d85767418072337fe2dd95e2564d9fdfc8f46e55436a09
5
5
  SHA512:
6
- metadata.gz: abb90ac13df5ce70438110572e462e51420d2a3d8c9c3cc766a00bf2c1897952e6d75a4c7bd219c5c5cc25ef6ab5dafaea62ec6ebb3ed14633d70343a6edebd5
7
- data.tar.gz: c86bae0d3eea9a489d6be29ad49a3eea56a0e6bc93dc62506d321a1ab84d7f61b8e6dbd9779805d365fcd85f6f213055ec2d0c41b84333ec26c65c56d8095e5a
6
+ metadata.gz: fcc54fa2294ac6fbdcd046582d2f7ed74855e79e66af8f10af6e48e68599aa2f8a29a5b9bd29136cc02fe5ff3d44c1b07943643a7f6a003576bd1ecd3283fc7d
7
+ data.tar.gz: 0f45f44be69ba3440974efd2e682d1e38cb58c2e7db0c23eff7dffa69c25b967ae9a10230bcafd3051e909e384540c524d7fddd2f47f96faffb3b15590ff5a6c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0 — 2026-04-07
4
+
5
+ ### Added
6
+
7
+ - **Modal `--compress` for pipe `--in`/`--out`** — `--compress` after `--in`
8
+ decompresses input, after `--out` compresses output. Enables mixed pipelines
9
+ like plain input → compressed output:
10
+ `omq pipe --in -c src --out --compress -c dst`.
11
+ Without `--in`/`--out`, `--compress` applies to both directions as before.
12
+
13
+ ### Fixed
14
+
15
+ - **Abort with clear message on decompression failure** — receiving an
16
+ uncompressed message with `--compress` now prints a hint instead of
17
+ silently killing the Async task with exit code 0.
18
+
3
19
  ## 0.5.4 — 2026-04-07
4
20
 
5
21
  ### Fixed
@@ -219,6 +219,8 @@ module OMQ
219
219
  rcvbuf: nil,
220
220
  conflate: false,
221
221
  compress: false,
222
+ compress_in: false,
223
+ compress_out: false,
222
224
  send_expr: nil,
223
225
  recv_expr: nil,
224
226
  parallel: nil,
@@ -346,7 +348,17 @@ module OMQ
346
348
  o.on("--conflate", "Keep only last message per subscriber (PUB/RADIO)") { opts[:conflate] = true }
347
349
 
348
350
  o.separator "\nCompression:"
349
- o.on("-z", "--compress", "Zstandard compression per frame") { require "zstd-ruby"; opts[:compress] = true }
351
+ o.on("-z", "--compress", "Zstandard compression per frame (modal with --in/--out)") do
352
+ require "zstd-ruby"
353
+ case pipe_side
354
+ when :in
355
+ opts[:compress_in] = true
356
+ when :out
357
+ opts[:compress_out] = true
358
+ else
359
+ opts[:compress] = true
360
+ end
361
+ end
350
362
 
351
363
  o.separator "\nProcessing (-e = incoming, -E = outgoing):"
352
364
  o.on("-e", "--recv-eval EXPR", "Eval Ruby for each incoming message ($F = parts)") { |v| opts[:recv_expr] = v }
@@ -44,6 +44,8 @@ module OMQ
44
44
  :rcvbuf,
45
45
  :conflate,
46
46
  :compress,
47
+ :compress_in,
48
+ :compress_out,
47
49
  :send_expr,
48
50
  :recv_expr,
49
51
  :parallel,
@@ -95,6 +95,8 @@ module OMQ
95
95
  # @return [Array<String>] decompressed frames
96
96
  def decompress(parts)
97
97
  @compress ? parts.map { |p| Zstd.decompress(p) } : parts
98
+ rescue
99
+ abort "omq: decompression failed (did the sender use --compress?)"
98
100
  end
99
101
  end
100
102
  end
data/lib/omq/cli/pipe.rb CHANGED
@@ -13,6 +13,8 @@ module OMQ
13
13
  def initialize(config)
14
14
  @config = config
15
15
  @fmt = Formatter.new(config.format, compress: config.compress)
16
+ @fmt_in = Formatter.new(config.format, compress: config.compress_in || config.compress)
17
+ @fmt_out = Formatter.new(config.format, compress: config.compress_out || config.compress)
16
18
  end
17
19
 
18
20
 
@@ -112,10 +114,10 @@ module OMQ
112
114
  loop do
113
115
  parts = @pull.receive
114
116
  break if parts.nil?
115
- parts = @fmt.decompress(parts)
117
+ parts = @fmt_in.decompress(parts)
116
118
  parts = eval_recv_expr(parts)
117
119
  if parts && !parts.empty?
118
- out = @fmt.compress(parts)
120
+ out = @fmt_out.compress(parts)
119
121
  @push.send(out)
120
122
  end
121
123
  i += 1
@@ -179,10 +181,11 @@ module OMQ
179
181
  # Pack worker config into a shareable Hash passed via omq.data —
180
182
  # Ruby 4.0 forbids Ractor blocks from closing over outer locals.
181
183
  ::Ractor.make_shareable({
182
- recv_src: config.recv_expr,
183
- fmt_format: config.format,
184
- fmt_compr: config.compress,
185
- n_count: config.count,
184
+ recv_src: config.recv_expr,
185
+ fmt_format: config.format,
186
+ compr_in: config.compress_in || config.compress,
187
+ compr_out: config.compress_out || config.compress,
188
+ n_count: config.count,
186
189
  })
187
190
  end
188
191
 
@@ -197,7 +200,8 @@ module OMQ
197
200
  begin_proc, end_proc, eval_proc =
198
201
  OMQ::CLI::ExpressionEvaluator.compile_inside_ractor(d[:recv_src])
199
202
 
200
- formatter = OMQ::CLI::Formatter.new(d[:fmt_format], compress: d[:fmt_compr])
203
+ fmt_in = OMQ::CLI::Formatter.new(d[:fmt_format], compress: d[:compr_in])
204
+ fmt_out = OMQ::CLI::Formatter.new(d[:fmt_format], compress: d[:compr_out])
201
205
  # Use a dedicated context object so @ivar expressions in BEGIN/END/eval
202
206
  # work inside Ractors (self in a Ractor is shareable; Object.new is not).
203
207
  _ctx = Object.new
@@ -210,20 +214,20 @@ module OMQ
210
214
  parts = pull_p.receive
211
215
  break if parts.nil?
212
216
  parts = OMQ::CLI::ExpressionEvaluator.normalize_result(
213
- _ctx.instance_exec(formatter.decompress(parts), &eval_proc)
217
+ _ctx.instance_exec(fmt_in.decompress(parts), &eval_proc)
214
218
  )
215
219
  next if parts.nil?
216
- push_p << formatter.compress(parts) unless parts.empty?
220
+ push_p << fmt_out.compress(parts) unless parts.empty?
217
221
  end
218
222
  else
219
223
  loop do
220
224
  parts = pull_p.receive
221
225
  break if parts.nil?
222
226
  parts = OMQ::CLI::ExpressionEvaluator.normalize_result(
223
- _ctx.instance_exec(formatter.decompress(parts), &eval_proc)
227
+ _ctx.instance_exec(fmt_in.decompress(parts), &eval_proc)
224
228
  )
225
229
  next if parts.nil?
226
- push_p << formatter.compress(parts) unless parts.empty?
230
+ push_p << fmt_out.compress(parts) unless parts.empty?
227
231
  end
228
232
  end
229
233
  else
@@ -231,13 +235,13 @@ module OMQ
231
235
  n_count.times do
232
236
  parts = pull_p.receive
233
237
  break if parts.nil?
234
- push_p << formatter.compress(formatter.decompress(parts))
238
+ push_p << fmt_out.compress(fmt_in.decompress(parts))
235
239
  end
236
240
  else
237
241
  loop do
238
242
  parts = pull_p.receive
239
243
  break if parts.nil?
240
- push_p << formatter.compress(formatter.decompress(parts))
244
+ push_p << fmt_out.compress(fmt_in.decompress(parts))
241
245
  end
242
246
  end
243
247
  end
@@ -246,7 +250,7 @@ module OMQ
246
250
  out = OMQ::CLI::ExpressionEvaluator.normalize_result(
247
251
  _ctx.instance_exec(&end_proc)
248
252
  )
249
- push_p << formatter.compress(out) if out && !out.empty?
253
+ push_p << fmt_out.compress(out) if out && !out.empty?
250
254
  end
251
255
  end
252
256
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OMQ
4
4
  module CLI
5
- VERSION = "0.5.4"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
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.5.4
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Wenger