omq-cli 0.18.0 → 0.19.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +16 -1
- data/lib/omq/cli/base_runner.rb +6 -0
- data/lib/omq/cli/cli_parser.rb +72 -15
- data/lib/omq/cli/config.rb +1 -0
- data/lib/omq/cli/parallel_worker.rb +1 -1
- data/lib/omq/cli/pipe.rb +9 -1
- data/lib/omq/cli/pipe_worker.rb +1 -1
- data/lib/omq/cli/socket_setup.rb +26 -1
- data/lib/omq/cli/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 92ca3f7bf414254b6ab93d4ff6282e1ca714292f6d7119c85cdb8d5f8e2e85c5
|
|
4
|
+
data.tar.gz: '021193bf3cf3785355f9592087ca1b182b50e4fb43fb8cf4a5590b9b75390da5'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 34500b01e5928851464136a9aeb9a5e2d6c76df95ae14f221068fcc399546b48abe662f0fdd68a9b1a73bde52b2fb20b3085dd9d1a14a08426f7baa40c0f224f
|
|
7
|
+
data.tar.gz: '0319a006c9bfe02acc713676f6db87dfb93314b059af1cc0c25a8a7efb2abfa70ecaf9b5817047332861a8a71f77a5711608fe6fab7d111b7349b02704029e5f'
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.19.0 — 2026-08-03
|
|
4
|
+
|
|
5
|
+
- **Rust backend selection via `--backend rust`.** Loads
|
|
6
|
+
`omq-backend-rust` and passes `backend: :rust` to socket
|
|
7
|
+
constructors.
|
|
8
|
+
- **Monorepo import.** `omq-cli` now lives under `gems/omq-cli` in
|
|
9
|
+
`omq.rb` and participates in monorepo test and release tasks.
|
|
10
|
+
|
|
3
11
|
## 0.17.1 — 2026-05-04
|
|
4
12
|
|
|
5
13
|
- bump deps
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://rubygems.org/gems/omq-cli)
|
|
4
4
|
[](LICENSE)
|
|
5
|
-
[](https://www.ruby-lang.org)
|
|
6
6
|
|
|
7
7
|
A command-line tool that speaks every ZeroMQ socket pattern, transforms
|
|
8
8
|
messages with inline Ruby, parallelizes across Ractors, encrypts with CURVE,
|
|
@@ -75,6 +75,21 @@ omq push -c@work # IPC abstract namespace (@name → ipc://@
|
|
|
75
75
|
Multiple endpoints are allowed — `omq pull -b tcp://:5557 -b tcp://:5558` binds both.
|
|
76
76
|
Pipe takes two positional endpoints (input, output) or uses `--in`/`--out` for multiple per side.
|
|
77
77
|
|
|
78
|
+
## Backends
|
|
79
|
+
|
|
80
|
+
The default backend is the pure Ruby engine.
|
|
81
|
+
|
|
82
|
+
| Flag | Backend |
|
|
83
|
+
|------|---------|
|
|
84
|
+
| `--backend ruby` | Pure Ruby backend, default |
|
|
85
|
+
| `--backend rust` | Rust backend from `omq-backend-rust` |
|
|
86
|
+
| `--backend libzmq` | libzmq backend from `omq-backend-libzmq` |
|
|
87
|
+
| `--backend ffi` or `--ffi` | Compatibility name for the libzmq backend |
|
|
88
|
+
|
|
89
|
+
Optional backends must be installed next to `omq-cli`.
|
|
90
|
+
Set `OMQ_BACKEND=ruby|rust|libzmq` to choose a default backend.
|
|
91
|
+
Use `-v` to print the effective backend at startup.
|
|
92
|
+
|
|
78
93
|
## Socket types
|
|
79
94
|
|
|
80
95
|
### Unidirectional (send-only / recv-only)
|
data/lib/omq/cli/base_runner.rb
CHANGED
|
@@ -25,6 +25,7 @@ module OMQ
|
|
|
25
25
|
# @return [void]
|
|
26
26
|
def call(task)
|
|
27
27
|
set_process_title
|
|
28
|
+
log_backend
|
|
28
29
|
setup_socket
|
|
29
30
|
start_event_monitor
|
|
30
31
|
maybe_start_transient_monitor(task)
|
|
@@ -557,6 +558,11 @@ module OMQ
|
|
|
557
558
|
end
|
|
558
559
|
|
|
559
560
|
|
|
561
|
+
def log_backend
|
|
562
|
+
log("backend: #{SocketSetup.backend_name(config)}")
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
|
|
560
566
|
# Always attached so protocol-level disconnect events can kill
|
|
561
567
|
# the socket. Verbose gating lives inside the callback:
|
|
562
568
|
# -vv log connect/disconnect/retry/timeout events
|
data/lib/omq/cli/cli_parser.rb
CHANGED
|
@@ -277,7 +277,8 @@ module OMQ
|
|
|
277
277
|
recv_maxsz: nil,
|
|
278
278
|
curve_server: false,
|
|
279
279
|
curve_server_key: nil,
|
|
280
|
-
crypto:
|
|
280
|
+
crypto: nil,
|
|
281
|
+
backend: :ruby,
|
|
281
282
|
ffi: false,
|
|
282
283
|
}.freeze
|
|
283
284
|
|
|
@@ -331,6 +332,7 @@ module OMQ
|
|
|
331
332
|
def parse(argv)
|
|
332
333
|
opts = DEFAULT_OPTS.transform_values { |v| v.is_a?(Array) ? v.dup : v }
|
|
333
334
|
pipe_side = nil # nil = legacy positional mode; :in/:out = modal
|
|
335
|
+
explicit_backend = false
|
|
334
336
|
|
|
335
337
|
parser = OptionParser.new do |o|
|
|
336
338
|
o.banner = "Usage: omq TYPE [options]\n\n" \
|
|
@@ -462,8 +464,6 @@ module OMQ
|
|
|
462
464
|
o.on("--curve-server-key KEY", "Enable CURVE as client (server's Z85 public key)") { |v| opts[:curve_server_key] = v }
|
|
463
465
|
o.on("--crypto BACKEND", "Crypto backend: rbnacl (default) or nuckle (pure Ruby, DANGEROUS)") { |v| opts[:crypto] = v }
|
|
464
466
|
o.separator " Install libsodium: apt install libsodium-dev / brew install libsodium"
|
|
465
|
-
o.separator " Env vars: OMQ_SERVER_KEY (client), OMQ_SERVER_PUBLIC + OMQ_SERVER_SECRET (server)"
|
|
466
|
-
o.separator " OMQ_CRYPTO (backend: rbnacl or nuckle)"
|
|
467
467
|
|
|
468
468
|
o.separator "\nOther:"
|
|
469
469
|
o.on("-v", "--verbose", "Verbosity: -v endpoints, -vv events, -vvv messages") { opts[:verbose] += 1 }
|
|
@@ -472,20 +472,22 @@ module OMQ
|
|
|
472
472
|
}
|
|
473
473
|
o.on("-q", "--quiet", "Suppress message output") { opts[:quiet] = true }
|
|
474
474
|
o.on( "--transient", "Exit when all peers disconnect") { opts[:transient] = true }
|
|
475
|
-
o.on( "--
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
475
|
+
o.on( "--backend BACKEND", %w[ruby rust libzmq ffi],
|
|
476
|
+
"Socket backend: ruby, rust, or libzmq") do |v|
|
|
477
|
+
backend = normalize_backend(v.to_sym)
|
|
478
|
+
load_socket_backend!(backend)
|
|
479
|
+
opts[:backend] = backend
|
|
480
|
+
opts[:ffi] = false
|
|
481
|
+
explicit_backend = true
|
|
482
|
+
end
|
|
483
|
+
o.on( "--ffi", "Alias for --backend libzmq") do
|
|
484
|
+
load_socket_backend!(:libzmq)
|
|
485
|
+
opts[:backend] = :libzmq
|
|
481
486
|
opts[:ffi] = true
|
|
487
|
+
explicit_backend = true
|
|
482
488
|
end
|
|
483
489
|
o.on("-V", "--version") {
|
|
484
|
-
|
|
485
|
-
require_relative "../../../../omq/lib/omq/version"
|
|
486
|
-
else
|
|
487
|
-
require "omq/version"
|
|
488
|
-
end
|
|
490
|
+
require "omq/version"
|
|
489
491
|
puts "omq-cli #{OMQ::CLI::VERSION} (omq #{OMQ::VERSION})"
|
|
490
492
|
exit
|
|
491
493
|
}
|
|
@@ -496,6 +498,12 @@ module OMQ
|
|
|
496
498
|
o.on("--examples") { CLI.page EXAMPLES
|
|
497
499
|
exit }
|
|
498
500
|
|
|
501
|
+
o.separator "\nEnv vars:"
|
|
502
|
+
o.separator " OMQ_BACKEND (socket backend: ruby, rust, or libzmq)"
|
|
503
|
+
o.separator " OMQ_SERVER_KEY (client CURVE server key)"
|
|
504
|
+
o.separator " OMQ_SERVER_PUBLIC + OMQ_SERVER_SECRET (server CURVE keypair)"
|
|
505
|
+
o.separator " OMQ_CRYPTO (CURVE crypto backend: rbnacl or nuckle)"
|
|
506
|
+
|
|
499
507
|
o.separator "\nExit codes: 0 = success, 1 = error, 2 = timeout"
|
|
500
508
|
end
|
|
501
509
|
|
|
@@ -517,6 +525,8 @@ module OMQ
|
|
|
517
525
|
opts[:type_name] = type_name.downcase
|
|
518
526
|
end
|
|
519
527
|
|
|
528
|
+
apply_env_backend!(opts) if opts[:type_name] && !explicit_backend
|
|
529
|
+
|
|
520
530
|
# Host shorthand (tcp://*:PORT, tcp://:PORT, tcp://localhost:PORT)
|
|
521
531
|
# is normalized inside OMQ::Transport::TCP — see its
|
|
522
532
|
# #normalize_bind_host / #normalize_connect_host / #loopback_host.
|
|
@@ -567,6 +577,53 @@ module OMQ
|
|
|
567
577
|
end
|
|
568
578
|
|
|
569
579
|
|
|
580
|
+
# Loads an optional OMQ socket backend while parsing backend flags.
|
|
581
|
+
#
|
|
582
|
+
def load_socket_backend!(backend)
|
|
583
|
+
case backend
|
|
584
|
+
when :ruby
|
|
585
|
+
nil
|
|
586
|
+
when :rust
|
|
587
|
+
require "omq/backend/rust"
|
|
588
|
+
when :libzmq
|
|
589
|
+
require "omq/backend/libzmq"
|
|
590
|
+
end
|
|
591
|
+
rescue LoadError => e
|
|
592
|
+
case backend
|
|
593
|
+
when :rust
|
|
594
|
+
abort "omq: --backend rust requires the omq-backend-rust gem (#{e.message})"
|
|
595
|
+
when :libzmq
|
|
596
|
+
abort "omq: --backend #{backend} requires the omq-backend-libzmq gem and system libzmq 4.x (#{e.message})"
|
|
597
|
+
else
|
|
598
|
+
abort "omq: could not load backend #{backend} (#{e.message})"
|
|
599
|
+
end
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
# Applies OMQ_BACKEND when no explicit backend flag was given.
|
|
604
|
+
#
|
|
605
|
+
def apply_env_backend!(opts)
|
|
606
|
+
env_backend = ENV["OMQ_BACKEND"]
|
|
607
|
+
return if env_backend.nil? || env_backend.empty?
|
|
608
|
+
|
|
609
|
+
unless %w[ruby rust libzmq].include?(env_backend)
|
|
610
|
+
abort "omq: invalid OMQ_BACKEND=#{env_backend.inspect} (use ruby, rust, or libzmq)"
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
backend = env_backend.to_sym
|
|
614
|
+
load_socket_backend!(backend)
|
|
615
|
+
opts[:backend] = backend
|
|
616
|
+
opts[:ffi] = false
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
# Maps legacy CLI spelling to the backend name supported by omq.
|
|
621
|
+
#
|
|
622
|
+
def normalize_backend(backend)
|
|
623
|
+
backend == :ffi ? :libzmq : backend
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
|
|
570
627
|
# Validates option combinations, aborting on invalid combos.
|
|
571
628
|
#
|
|
572
629
|
# @param opts [Hash] parsed options from {#parse}
|
|
@@ -625,7 +682,7 @@ module OMQ
|
|
|
625
682
|
end
|
|
626
683
|
|
|
627
684
|
(opts[:connects] + opts[:binds]).each do |url|
|
|
628
|
-
abort "
|
|
685
|
+
abort "ruby:// not supported in CLI, use tcp:// or ipc://" if url.include?("ruby://")
|
|
629
686
|
end
|
|
630
687
|
|
|
631
688
|
all_urls = if type_name == "pipe"
|
data/lib/omq/cli/config.rb
CHANGED
|
@@ -48,7 +48,7 @@ module OMQ
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
def setup_socket
|
|
51
|
-
@sock =
|
|
51
|
+
@sock = OMQ.const_get(@socket_sym).new(**OMQ::CLI::SocketSetup.backend_kwargs(@config))
|
|
52
52
|
OMQ::CLI::SocketSetup.apply_options(@sock, @config)
|
|
53
53
|
OMQ::CLI::SocketSetup.apply_recv_maxsz(@sock, @config)
|
|
54
54
|
@sock.identity = @config.identity if @config.identity
|
data/lib/omq/cli/pipe.rb
CHANGED
|
@@ -46,6 +46,7 @@ module OMQ
|
|
|
46
46
|
|
|
47
47
|
def run_sequential(task)
|
|
48
48
|
set_pipe_process_title
|
|
49
|
+
log_backend
|
|
49
50
|
in_eps, out_eps = resolve_endpoints
|
|
50
51
|
@pull, @push = build_pull_push(in_eps, out_eps)
|
|
51
52
|
compile_expr
|
|
@@ -83,7 +84,7 @@ module OMQ
|
|
|
83
84
|
|
|
84
85
|
|
|
85
86
|
def build_pull_push(in_eps, out_eps)
|
|
86
|
-
kwargs = config
|
|
87
|
+
kwargs = SocketSetup.backend_kwargs(config)
|
|
87
88
|
|
|
88
89
|
pull = OMQ::PULL.new(**kwargs).tap do |sock|
|
|
89
90
|
SocketSetup.apply_options(sock, config)
|
|
@@ -152,6 +153,7 @@ module OMQ
|
|
|
152
153
|
|
|
153
154
|
def run_parallel(task)
|
|
154
155
|
set_pipe_process_title
|
|
156
|
+
log_backend
|
|
155
157
|
OMQ.freeze_for_ractors!
|
|
156
158
|
|
|
157
159
|
in_eps, out_eps = resolve_endpoints
|
|
@@ -240,6 +242,12 @@ module OMQ
|
|
|
240
242
|
end
|
|
241
243
|
end
|
|
242
244
|
|
|
245
|
+
|
|
246
|
+
def log_backend
|
|
247
|
+
return unless config.verbose >= 1
|
|
248
|
+
$stderr.write("#{Term.log_prefix(config.timestamps)}omq: backend: #{SocketSetup.backend_name(config)}\n")
|
|
249
|
+
end
|
|
250
|
+
|
|
243
251
|
end
|
|
244
252
|
end
|
|
245
253
|
end
|
data/lib/omq/cli/pipe_worker.rb
CHANGED
|
@@ -38,7 +38,7 @@ module OMQ
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
def setup_sockets
|
|
41
|
-
kwargs = @config
|
|
41
|
+
kwargs = OMQ::CLI::SocketSetup.backend_kwargs(@config)
|
|
42
42
|
@pull = OMQ::PULL.new(**kwargs)
|
|
43
43
|
@push = OMQ::PUSH.new(**kwargs)
|
|
44
44
|
OMQ::CLI::SocketSetup.apply_options(@pull, @config)
|
data/lib/omq/cli/socket_setup.rb
CHANGED
|
@@ -86,6 +86,31 @@ module OMQ
|
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
|
|
89
|
+
# Returns socket constructor kwargs for the selected backend.
|
|
90
|
+
#
|
|
91
|
+
def self.backend_kwargs(config)
|
|
92
|
+
backend = backend_name(config)
|
|
93
|
+
return {} if backend.nil? || backend == :ruby
|
|
94
|
+
|
|
95
|
+
{ backend: backend }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# Returns the effective backend name after legacy --ffi handling.
|
|
100
|
+
#
|
|
101
|
+
def self.backend_name(config)
|
|
102
|
+
backend = if config.respond_to?(:ffi) && config.ffi
|
|
103
|
+
:libzmq
|
|
104
|
+
elsif config.respond_to?(:backend)
|
|
105
|
+
config.backend
|
|
106
|
+
else
|
|
107
|
+
:ruby
|
|
108
|
+
end
|
|
109
|
+
backend = :libzmq if backend == :ffi
|
|
110
|
+
backend || :ruby
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
89
114
|
# Apply common socket options from +config+ to +sock+.
|
|
90
115
|
#
|
|
91
116
|
def self.apply_options(sock, config)
|
|
@@ -105,7 +130,7 @@ module OMQ
|
|
|
105
130
|
# Create and fully configure a socket from +klass+ and +config+.
|
|
106
131
|
#
|
|
107
132
|
def self.build(klass, config)
|
|
108
|
-
sock =
|
|
133
|
+
sock = klass.new(**backend_kwargs(config))
|
|
109
134
|
sock.conflate = true if config.conflate && %w[pub radio].include?(config.type_name)
|
|
110
135
|
apply_options(sock, config)
|
|
111
136
|
apply_recv_maxsz(sock, config)
|
data/lib/omq/cli/version.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.
|
|
4
|
+
version: 0.19.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '0.
|
|
18
|
+
version: '0.28'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '0.
|
|
25
|
+
version: '0.28'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: ffi
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -132,7 +132,7 @@ files:
|
|
|
132
132
|
- lib/omq/cli/term.rb
|
|
133
133
|
- lib/omq/cli/transient_monitor.rb
|
|
134
134
|
- lib/omq/cli/version.rb
|
|
135
|
-
homepage: https://github.com/
|
|
135
|
+
homepage: https://github.com/zeromq/omq.rb/tree/main/gems/omq-cli
|
|
136
136
|
licenses:
|
|
137
137
|
- ISC
|
|
138
138
|
metadata: {}
|
|
@@ -150,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
150
150
|
- !ruby/object:Gem::Version
|
|
151
151
|
version: '0'
|
|
152
152
|
requirements: []
|
|
153
|
-
rubygems_version: 4.0.
|
|
153
|
+
rubygems_version: 4.0.16
|
|
154
154
|
specification_version: 4
|
|
155
155
|
summary: ZeroMQ CLI — pipe, filter, and transform messages from the terminal
|
|
156
156
|
test_files: []
|