omq-cli 0.14.8 → 0.15.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: 108eeb712d98cda6762591002a5a7a6e24d341b579c6f9734f5a8d78adb2e481
4
- data.tar.gz: a603b8c354cb14b6cfa8aed2a13798f9e9a51ecf34c31ab83b6119a36e9a88bb
3
+ metadata.gz: 01d85d72c83e9ad13715a18fcf2aac262ffc3abf1940f1b4c88b4f919913b044
4
+ data.tar.gz: c8c44569da1411027c0b9df3ebb9280c56bc4036d55cfd7af408235ee0a2ba04
5
5
  SHA512:
6
- metadata.gz: 03210f226733ee6baa9acf26fc5e37617dbe6ca8040bd73529701d60994999d1a0baa8571b10852654892e1add49333c6c8bc38c442d91a349c4c0e49a749379
7
- data.tar.gz: bfd7327cb515ae2133de3ec152b3c6f7ee5c68398b74f46fbd00d4ae060569bc782d4332e043e4b9eb1f0a53dd0ba5fa33ab84a72c322708e3aceee5febaad89
6
+ metadata.gz: b5769bb94c0f8d6cae351aae3d0dcba2694a4abf894bc1f89479bcb4aa7d41e3058c3d4c9c8788b9d26529a846c314adb61398decc77b8528a080950302614c7
7
+ data.tar.gz: 5dbcde145f0fca2bdfc44084c508c902a8dfec7a58519c1e5e4f24e6e79af34dcede9dc1b2d538d31a35e7108f4b6556b9a0d3958a83c830a8b6bec47e5f90dd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.15.0 — 2026-04-14
4
+
5
+ ### Changed
6
+
7
+ - Use omq-rfc-zstd ~> 0.2
8
+
9
+ ## 0.14.9 — 2026-04-14
10
+
11
+ ### Fixed
12
+
13
+ - **Bind-mode one-shot senders now wait for a peer before firing.**
14
+ `omq push -b tcp://:5050 -ME '"foo"*3'` used to bind, queue the
15
+ message into HWM, close the socket, and exit — frequently before
16
+ any PULL had even connected, surfacing as a mysterious
17
+ linger-timeout on exit. `needs_peer_wait?` now also returns true
18
+ for bind-mode senders whose send plan is bounded or scheduled
19
+ (`-d` / `-f` / `-E` / `-i`), so the runner blocks on
20
+ `peer_connected.wait` before sending and then drains cleanly via
21
+ linger on close. Interactive stdin is unchanged — typing isn't
22
+ gated on a peer.
23
+ - **`--count N` now works with `-d` / `-f` / `-E` one-shot sends.**
24
+ Previously only `-i` / stdin respected `--count`; a pure-generator
25
+ run fired exactly once regardless. The `-d`/`-f` and `-E` branches
26
+ in `run_send_logic` now loop `n` times (default 1).
27
+ - **`^C` while paging `--examples` is quiet.** Hitting ^C in the
28
+ pager used to leak an `Interrupt` stack trace from `IO.popen`;
29
+ `CLI.page` now rescues `Interrupt` alongside `Errno::EPIPE`.
30
+
31
+ ### Changed
32
+
33
+ - **`--examples` output is ASCII-only and tightened up.** Replaced
34
+ the two em-dashes in the Marshal section with ASCII parentheses,
35
+ added a note to the Pipe section explaining that `@work` /
36
+ `@sink` are Linux abstract-namespace unix sockets
37
+ (`ipc://@name`), Linux-only, and to fall back to `ipc:///tmp/…`
38
+ on macOS/BSD. Marshal and Compression prose trimmed from
39
+ paragraph form to 2-3 line summaries.
40
+
3
41
  ## 0.14.8 — 2026-04-14
4
42
 
5
43
  ### Changed
@@ -141,7 +141,21 @@ module OMQ
141
141
 
142
142
 
143
143
  def needs_peer_wait?
144
- !config.recv_only? && (config.connects.any? || config.type_name == "router")
144
+ return false if config.recv_only?
145
+ return true if config.connects.any?
146
+ return true if config.type_name == "router"
147
+
148
+ # Bind-mode senders with a bounded or scheduled send plan:
149
+ # wait for the first peer so a one-shot `-d` / `-E` doesn't
150
+ # just queue into HWM and then exit before anyone is
151
+ # listening. Interactive stdin still goes through unwaited
152
+ # so typing isn't gated on a peer.
153
+ config.binds.any? && bounded_or_scheduled_send?
154
+ end
155
+
156
+
157
+ def bounded_or_scheduled_send?
158
+ config.interval || config.data || config.file || @send_eval_proc
145
159
  end
146
160
 
147
161
 
@@ -205,14 +219,18 @@ module OMQ
205
219
  if config.interval
206
220
  run_interval_send(n)
207
221
  elsif config.data || config.file
222
+ # One-shot from -d/-f. --count N fires the same payload N times.
208
223
  parts = eval_send_expr(read_next)
209
- send_msg(parts) if parts
224
+ (n && n > 0 ? n : 1).times { send_msg(parts) } if parts
210
225
  elsif stdin_ready?
211
226
  run_stdin_send(n)
212
227
  elsif @send_eval_proc
213
- # Pure generator: -e/-E with no stdin input, fire once.
214
- parts = eval_send_expr(nil)
215
- send_msg(parts) if parts
228
+ # Pure generator: -e/-E with no stdin input. Fire once by
229
+ # default, --count N fires N times.
230
+ (n && n > 0 ? n : 1).times do
231
+ parts = eval_send_expr(nil)
232
+ send_msg(parts) if parts
233
+ end
216
234
  elsif config.stdin_is_tty
217
235
  # Bare interactive invocation on a terminal: read lines from
218
236
  # the tty until the user hits ^D.
@@ -75,10 +75,15 @@ module OMQ
75
75
  | PUSH |-------->| pipe |-------->| PULL |
76
76
  +------+ +------+ +------+
77
77
 
78
+ # @work / @sink below are Linux abstract-namespace unix
79
+ # sockets (ipc://@name) -- no path on disk, cleaned up
80
+ # automatically. Linux only. Use ipc:///tmp/work etc.
81
+ # on macOS/BSD.
82
+
78
83
  # terminal 1: producer
79
84
  echo -e "hello\nworld" | omq push -b@work
80
85
 
81
- # terminal 2: worker -- uppercase each message
86
+ # terminal 2: worker (uppercase each message)
82
87
  omq pipe -c@work -c@sink -e 'it.map(&:upcase)'
83
88
  # terminal 3: collector
84
89
  omq pull -b@sink
@@ -89,10 +94,10 @@ module OMQ
89
94
  # exit when producer disconnects (--transient)
90
95
  omq pipe -c@work -c@sink --transient -e 'it.map(&:upcase)'
91
96
 
92
- # fan-in: multiple sources -> one sink
97
+ # fan-in (multiple sources -> one sink)
93
98
  omq pipe --in -c@work1 -c@work2 --out -c@sink -e 'it.map(&:upcase)'
94
99
 
95
- # fan-out: one source -> multiple sinks (round-robin)
100
+ # fan-out (one source -> multiple sinks, round-robin)
96
101
  omq pipe --in -b tcp://:5555 --out -c@sink1 -c@sink2 -e 'it'
97
102
 
98
103
  -- CLIENT / SERVER (draft) ----------------------------------
@@ -125,15 +130,13 @@ module OMQ
125
130
 
126
131
  -- Marshal (arbitrary Ruby objects) -------------------------
127
132
 
128
- # With -M, each message on the wire is one Marshal-dumped
129
- # Ruby object. Inside -e/-E, `it` is that raw object not
130
- # an Array of frames — so you can send/receive scalars,
131
- # hashes, custom classes, whatever Marshal handles.
133
+ # -M: each message is one Marshal-dumped Ruby object.
134
+ # Inside -e/-E, `it` is the raw object (not an Array).
132
135
 
133
- # send a bare string, receive a { string => encoding } hash
134
- omq push -b tcp://:5557 -ME '"foo"'
135
- omq pull -c tcp://:5557 -Mvvv -e '{it => it.encoding}'
136
- # output: {"foo" => #<Encoding:UTF-8>}
136
+ # send a bare string; receiver transforms it to { string => encoding } hash
137
+ omq push -b tcp://:5557 -ME '"foo" * 3'
138
+ omq pull -c tcp://:5557 -Me '{it => it.encoding}'
139
+ # output: {"foofoofoo" => #<Encoding:UTF-8>}
137
140
 
138
141
  # -vvv traces render the app object, not wire bytes
139
142
  omq push -b tcp://:5557 -ME '{now: Time.now, pid: Process.pid}' -vvv
@@ -141,11 +144,9 @@ module OMQ
141
144
 
142
145
  -- Compression ----------------------------------------------
143
146
 
144
- # ZMTP-Zstd is negotiated transparently during the handshake.
145
- # Receive-capable sockets (pull, sub, rep, ...) advertise the
146
- # profile by default in passive mode: they decode compressed
147
- # frames from an active sender but never compress their own
148
- # outgoing frames. Use -z / -Z on the sender to opt it in.
147
+ # ZMTP-Zstd is negotiated during the handshake.
148
+ # Recv sockets advertise it passively by default.
149
+ # Use -z on the sender to compress outgoing frames.
149
150
  omq pull --bind tcp://:5557 &
150
151
  echo "compressible data" | omq push --connect tcp://localhost:5557 -z
151
152
 
@@ -49,9 +49,9 @@ module OMQ
49
49
  # their push/pull ends of a single pipe.
50
50
  def self.apply_compression(sock, config, type_name)
51
51
  if config.compress
52
- sock.compression = OMQ::RFC::Zstd::Compression.auto(level: config.compress_level || -3)
52
+ sock.compression = OMQ::Compression::Zstd.auto(level: config.compress_level || -3)
53
53
  elsif !PURE_SEND_TYPES.include?(type_name)
54
- sock.compression = OMQ::RFC::Zstd::Compression.auto(passive: true)
54
+ sock.compression = OMQ::Compression::Zstd.auto(passive: true)
55
55
  end
56
56
  end
57
57
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OMQ
4
4
  module CLI
5
- VERSION = "0.14.8"
5
+ VERSION = "0.15.0"
6
6
  end
7
7
  end
data/lib/omq/cli.rb CHANGED
@@ -29,20 +29,28 @@ module OMQ
29
29
  class << self
30
30
  # @return [Proc, nil] registered outgoing message transform
31
31
  attr_reader :outgoing_proc
32
+
33
+
32
34
  # @return [Proc, nil] registered incoming message transform
33
35
  attr_reader :incoming_proc
34
36
 
37
+
35
38
  # Registers an outgoing message transform (used by -r scripts).
36
39
  #
37
40
  # @yield [Array<String>] message parts before sending
38
41
  # @return [Proc]
39
- def outgoing(&block) = @outgoing_proc = block
42
+ def outgoing(&block)
43
+ @outgoing_proc = block
44
+ end
45
+
40
46
 
41
47
  # Registers an incoming message transform (used by -r scripts).
42
48
  #
43
49
  # @yield [Array<String>] message parts after receiving
44
50
  # @return [Proc]
45
- def incoming(&block) = @incoming_proc = block
51
+ def incoming(&block)
52
+ @incoming_proc = block
53
+ end
46
54
  end
47
55
 
48
56
 
@@ -97,8 +105,8 @@ module OMQ
97
105
  end
98
106
  rescue Errno::ENOENT
99
107
  puts text
100
- rescue Errno::EPIPE
101
- # user quit pager early
108
+ rescue Errno::EPIPE, Interrupt
109
+ # user quit pager early (q) or hit ^C while paging
102
110
  end
103
111
 
104
112
 
@@ -123,6 +131,7 @@ module OMQ
123
131
  def run_keygen(argv)
124
132
  crypto_name = nil
125
133
  verbose = false
134
+
126
135
  while (arg = argv.shift)
127
136
  case arg
128
137
  when "--crypto"
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.14.8
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Wenger
@@ -119,14 +119,14 @@ dependencies:
119
119
  requirements:
120
120
  - - "~>"
121
121
  - !ruby/object:Gem::Version
122
- version: '0.1'
122
+ version: '0.2'
123
123
  type: :runtime
124
124
  prerelease: false
125
125
  version_requirements: !ruby/object:Gem::Requirement
126
126
  requirements:
127
127
  - - "~>"
128
128
  - !ruby/object:Gem::Version
129
- version: '0.1'
129
+ version: '0.2'
130
130
  - !ruby/object:Gem::Dependency
131
131
  name: msgpack
132
132
  requirement: !ruby/object:Gem::Requirement