nnq-cli 0.2.0 → 0.3.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 +21 -0
- data/lib/nnq/cli/base_runner.rb +8 -9
- data/lib/nnq/cli/cli_parser.rb +20 -12
- data/lib/nnq/cli/formatter.rb +4 -29
- data/lib/nnq/cli/pipe.rb +9 -7
- data/lib/nnq/cli/pipe_worker.rb +8 -10
- data/lib/nnq/cli/req_rep.rb +6 -9
- data/lib/nnq/cli/socket_setup.rb +10 -0
- data/lib/nnq/cli/surveyor_respondent.rb +6 -9
- data/lib/nnq/cli/version.rb +1 -1
- data/lib/nnq/cli.rb +13 -2
- metadata +12 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b3b69a427aa491a1d47cb1144cf96824469c9029658239250d0b98f9d69ae43a
|
|
4
|
+
data.tar.gz: 43e68cf5d450fa777e79dd8913d9381eb0b436fe08d6e193c90cb47ecc42e036
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: afc90caf9d6ba1bdfe488af48991af91a73a95d88ce5d6fe156f0255c7faef85de7b6016bb9db36c41be94c504c9ac8562ebd28ba20544f280afa00a8fff2ee9
|
|
7
|
+
data.tar.gz: 4fe278dcb3f5cdfc9171c6ebbb6de1cf2a30b49c01d1597b6c359cdb1d8903290be7ed068c7c7e2dab98001c9fac5207b544b5c6b1c611a18ebac1585baceedf
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0 — 2026-04-15
|
|
4
|
+
|
|
5
|
+
- **Compression switched from LZ4 to Zstd** via the new
|
|
6
|
+
[nnq-zstd](https://github.com/paddor/nnq-zstd) gem. `-z`
|
|
7
|
+
(fast, level −3) and `-Z` (balanced, level 3) are mutually
|
|
8
|
+
exclusive and map to transparent `NNQ::Zstd.wrap` decorators
|
|
9
|
+
around each socket. Sender-side dictionary training and in-band
|
|
10
|
+
dict shipping mean compression ratios on streams of similar
|
|
11
|
+
small messages are now dramatically better than the old
|
|
12
|
+
stateless LZ4 path. Both peers still have to pass `-z`/`-Z`;
|
|
13
|
+
there is no negotiation.
|
|
14
|
+
- **`-Z` / `--compress-high`** flag for balanced Zstd.
|
|
15
|
+
- **Formatter no longer knows about compression.** All per-message
|
|
16
|
+
compression state and logic moved out of `Formatter`; compression
|
|
17
|
+
is applied transparently at the socket boundary via the new
|
|
18
|
+
wrapper. Fewer code paths in runners.
|
|
19
|
+
- **`rlz4` dependency dropped** in favor of `nnq-zstd ~> 0.1`.
|
|
20
|
+
- **Lazy loading.** `nnq/zstd` (and therefore `rzstd` and the Rust
|
|
21
|
+
extension) is only required when `-z`/`-Z` is actually used,
|
|
22
|
+
keeping startup cost unchanged for non-compressing runs.
|
|
23
|
+
|
|
3
24
|
## 0.2.0 — 2026-04-15
|
|
4
25
|
|
|
5
26
|
- **Peer wait for bind-mode bounded senders** — `nnq push -b ... -d
|
data/lib/nnq/cli/base_runner.rb
CHANGED
|
@@ -20,7 +20,7 @@ module NNQ
|
|
|
20
20
|
def initialize(config, socket_class)
|
|
21
21
|
@config = config
|
|
22
22
|
@klass = socket_class
|
|
23
|
-
@fmt = Formatter.new(config.format
|
|
23
|
+
@fmt = Formatter.new(config.format)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
|
|
@@ -64,7 +64,8 @@ module NNQ
|
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
def create_socket
|
|
67
|
-
SocketSetup.build(@klass, config)
|
|
67
|
+
sock = SocketSetup.build(@klass, config)
|
|
68
|
+
SocketSetup.maybe_wrap_zstd(sock, config.compress)
|
|
68
69
|
end
|
|
69
70
|
|
|
70
71
|
|
|
@@ -288,9 +289,8 @@ module NNQ
|
|
|
288
289
|
# msg: 1-element Array. nnq sockets take a bare String body.
|
|
289
290
|
def send_msg(msg)
|
|
290
291
|
return if msg.empty?
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
@sock.send(msg.first)
|
|
292
|
+
body = config.format == :marshal ? Marshal.dump(msg.first) : msg.first
|
|
293
|
+
@sock.send(body)
|
|
294
294
|
transient_ready!
|
|
295
295
|
end
|
|
296
296
|
|
|
@@ -299,10 +299,9 @@ module NNQ
|
|
|
299
299
|
def recv_msg
|
|
300
300
|
raw = @sock.receive
|
|
301
301
|
return nil if raw.nil?
|
|
302
|
-
|
|
303
|
-
msg = [Marshal.load(msg.first)] if config.format == :marshal
|
|
302
|
+
body = config.format == :marshal ? Marshal.load(raw) : raw
|
|
304
303
|
transient_ready!
|
|
305
|
-
|
|
304
|
+
[body]
|
|
306
305
|
end
|
|
307
306
|
|
|
308
307
|
|
|
@@ -415,7 +414,7 @@ module NNQ
|
|
|
415
414
|
def set_process_title(endpoints: nil)
|
|
416
415
|
eps = endpoints || config.endpoints
|
|
417
416
|
title = ["nnq", config.type_name]
|
|
418
|
-
title << "-z" if config.compress
|
|
417
|
+
title << (config.compress == :balanced ? "-Z" : "-z") if config.compress
|
|
419
418
|
title << "-P#{config.parallel}" if config.parallel
|
|
420
419
|
eps.each do |ep|
|
|
421
420
|
title << (ep.respond_to?(:url) ? ep.url : ep.to_s)
|
data/lib/nnq/cli/cli_parser.rb
CHANGED
|
@@ -178,9 +178,9 @@ module NNQ
|
|
|
178
178
|
send_hwm: nil,
|
|
179
179
|
sndbuf: nil,
|
|
180
180
|
rcvbuf: nil,
|
|
181
|
-
compress:
|
|
182
|
-
compress_in:
|
|
183
|
-
compress_out:
|
|
181
|
+
compress: nil,
|
|
182
|
+
compress_in: nil,
|
|
183
|
+
compress_out: nil,
|
|
184
184
|
send_expr: nil,
|
|
185
185
|
recv_expr: nil,
|
|
186
186
|
parallel: nil,
|
|
@@ -295,16 +295,24 @@ module NNQ
|
|
|
295
295
|
o.on("--rcvbuf N", "SO_RCVBUF kernel buffer size (e.g. 4K, 1M)") { |v| opts[:rcvbuf] = parse_byte_size(v) }
|
|
296
296
|
|
|
297
297
|
o.separator "\nCompression:"
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
298
|
+
load_zstd = -> { require "nnq/zstd" }
|
|
299
|
+
set_compress = lambda do |sym|
|
|
300
|
+
load_zstd.call
|
|
301
|
+
target = case pipe_side
|
|
302
|
+
when :in then :compress_in
|
|
303
|
+
when :out then :compress_out
|
|
304
|
+
else :compress
|
|
305
|
+
end
|
|
306
|
+
if opts[target] && opts[target] != sym
|
|
307
|
+
abort "nnq: -z and -Z are mutually exclusive"
|
|
307
308
|
end
|
|
309
|
+
opts[target] = sym
|
|
310
|
+
end
|
|
311
|
+
o.on("-z", "--compress", "Zstd compression (fast, level -3; modal with --in/--out)") do
|
|
312
|
+
set_compress.call(:fast)
|
|
313
|
+
end
|
|
314
|
+
o.on("-Z", "--compress-high", "Zstd compression (balanced, level 3; modal with --in/--out)") do
|
|
315
|
+
set_compress.call(:balanced)
|
|
308
316
|
end
|
|
309
317
|
|
|
310
318
|
o.separator "\nProcessing (-e = incoming, -E = outgoing):"
|
data/lib/nnq/cli/formatter.rb
CHANGED
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module NNQ
|
|
4
4
|
module CLI
|
|
5
|
-
# Raised when LZ4 decompression fails.
|
|
6
|
-
class DecompressError < RuntimeError; end
|
|
7
|
-
|
|
8
5
|
# Handles encoding/decoding a single-body message in the configured
|
|
9
|
-
# format
|
|
6
|
+
# format. Compression is handled by the NNQ::Zstd decorator around
|
|
7
|
+
# the socket, not by the formatter.
|
|
10
8
|
#
|
|
11
9
|
# Unlike omq-cli's Formatter, nnq messages are not multipart — one
|
|
12
10
|
# `String` body per message. The API still accepts/returns a
|
|
@@ -14,10 +12,8 @@ module NNQ
|
|
|
14
12
|
# way.
|
|
15
13
|
class Formatter
|
|
16
14
|
# @param format [Symbol] wire format (:ascii, :quoted, :raw, :jsonl, :msgpack, :marshal)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@format = format
|
|
20
|
-
@compress = compress
|
|
15
|
+
def initialize(format)
|
|
16
|
+
@format = format
|
|
21
17
|
end
|
|
22
18
|
|
|
23
19
|
|
|
@@ -89,27 +85,6 @@ module NNQ
|
|
|
89
85
|
end
|
|
90
86
|
|
|
91
87
|
|
|
92
|
-
# Compresses the body with LZ4 if compression is enabled.
|
|
93
|
-
#
|
|
94
|
-
# @param msg [Array<String>] single-element array
|
|
95
|
-
# @return [Array<String>] optionally compressed
|
|
96
|
-
def compress(msg)
|
|
97
|
-
@compress ? msg.map { |p| RLZ4.compress(p) if p } : msg
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
# Decompresses the body with LZ4 if compression is enabled.
|
|
102
|
-
# nil/empty bodies pass through.
|
|
103
|
-
#
|
|
104
|
-
# @param msg [Array<String>] possibly compressed single-element array
|
|
105
|
-
# @return [Array<String>] decompressed
|
|
106
|
-
def decompress(msg)
|
|
107
|
-
@compress ? msg.map { |p| p && !p.empty? ? RLZ4.decompress(p) : p } : msg
|
|
108
|
-
rescue RLZ4::DecompressError
|
|
109
|
-
raise DecompressError, "decompression failed (did the sender use --compress?)"
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
|
|
113
88
|
# Formats a message body for human-readable preview (logging).
|
|
114
89
|
#
|
|
115
90
|
# @param msg [Array<String>] single-element array
|
data/lib/nnq/cli/pipe.rb
CHANGED
|
@@ -12,8 +12,8 @@ module NNQ
|
|
|
12
12
|
# @param config [Config] frozen CLI configuration
|
|
13
13
|
def initialize(config)
|
|
14
14
|
@config = config
|
|
15
|
-
@fmt_in = Formatter.new(config.format
|
|
16
|
-
@fmt_out = Formatter.new(config.format
|
|
15
|
+
@fmt_in = Formatter.new(config.format)
|
|
16
|
+
@fmt_out = Formatter.new(config.format)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
|
|
@@ -68,6 +68,8 @@ module NNQ
|
|
|
68
68
|
push = SocketSetup.build(NNQ::PUSH0, config)
|
|
69
69
|
SocketSetup.attach_endpoints(pull, in_eps, verbose: config.verbose)
|
|
70
70
|
SocketSetup.attach_endpoints(push, out_eps, verbose: config.verbose)
|
|
71
|
+
pull = SocketSetup.maybe_wrap_zstd(pull, config.compress_in || config.compress)
|
|
72
|
+
push = SocketSetup.maybe_wrap_zstd(push, config.compress_out || config.compress)
|
|
71
73
|
[pull, push]
|
|
72
74
|
end
|
|
73
75
|
|
|
@@ -103,12 +105,10 @@ module NNQ
|
|
|
103
105
|
loop do
|
|
104
106
|
body = @pull.receive
|
|
105
107
|
break if body.nil?
|
|
106
|
-
msg =
|
|
107
|
-
msg = eval_recv_expr(msg)
|
|
108
|
+
msg = eval_recv_expr([body])
|
|
108
109
|
|
|
109
110
|
if msg && !msg.empty?
|
|
110
|
-
|
|
111
|
-
@push.send(out.first)
|
|
111
|
+
@push.send(msg.first)
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
# Yield after send so send-pump fibers can drain the queue
|
|
@@ -163,7 +163,9 @@ module NNQ
|
|
|
163
163
|
def set_pipe_process_title
|
|
164
164
|
in_eps, out_eps = resolve_endpoints
|
|
165
165
|
title = ["nnq pipe"]
|
|
166
|
-
|
|
166
|
+
if (m = config.compress || config.compress_in || config.compress_out)
|
|
167
|
+
title << (m == :balanced ? "-Z" : "-z")
|
|
168
|
+
end
|
|
167
169
|
title << "-P#{config.parallel}" if config.parallel
|
|
168
170
|
title.concat(in_eps.map(&:url))
|
|
169
171
|
title << "->"
|
data/lib/nnq/cli/pipe_worker.rb
CHANGED
|
@@ -24,8 +24,8 @@ module NNQ
|
|
|
24
24
|
compile_expr
|
|
25
25
|
run_message_loop
|
|
26
26
|
run_end_block
|
|
27
|
-
rescue NNQ::
|
|
28
|
-
@error_port&.send(e.message)
|
|
27
|
+
rescue NNQ::Zstd::ProtocolError => e
|
|
28
|
+
@error_port&.send("zstd protocol error: #{e.message}")
|
|
29
29
|
ensure
|
|
30
30
|
@pull&.close
|
|
31
31
|
@push&.close
|
|
@@ -41,6 +41,8 @@ module NNQ
|
|
|
41
41
|
@push = NNQ::CLI::SocketSetup.build(NNQ::PUSH0, @config)
|
|
42
42
|
NNQ::CLI::SocketSetup.attach_endpoints(@pull, @in_eps, verbose: 0)
|
|
43
43
|
NNQ::CLI::SocketSetup.attach_endpoints(@push, @out_eps, verbose: 0)
|
|
44
|
+
@pull = NNQ::CLI::SocketSetup.maybe_wrap_zstd(@pull, @config.compress_in || @config.compress)
|
|
45
|
+
@push = NNQ::CLI::SocketSetup.maybe_wrap_zstd(@push, @config.compress_out || @config.compress)
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
|
|
@@ -86,8 +88,6 @@ module NNQ
|
|
|
86
88
|
def compile_expr
|
|
87
89
|
@begin_proc, @end_proc, @eval_proc =
|
|
88
90
|
NNQ::CLI::ExpressionEvaluator.compile_inside_ractor(@config.recv_expr)
|
|
89
|
-
@fmt_in = NNQ::CLI::Formatter.new(@config.format, compress: @config.compress_in || @config.compress)
|
|
90
|
-
@fmt_out = NNQ::CLI::Formatter.new(@config.format, compress: @config.compress_out || @config.compress)
|
|
91
91
|
@ctx = Object.new
|
|
92
92
|
@ctx.instance_exec(&@begin_proc) if @begin_proc
|
|
93
93
|
end
|
|
@@ -100,11 +100,10 @@ module NNQ
|
|
|
100
100
|
body = @pull.receive
|
|
101
101
|
break if body.nil?
|
|
102
102
|
msg = NNQ::CLI::ExpressionEvaluator.normalize_result(
|
|
103
|
-
@ctx.instance_exec(
|
|
103
|
+
@ctx.instance_exec([body], &@eval_proc)
|
|
104
104
|
)
|
|
105
105
|
unless msg.nil? || msg.empty?
|
|
106
|
-
|
|
107
|
-
@push.send(out.first)
|
|
106
|
+
@push.send(msg.first)
|
|
108
107
|
end
|
|
109
108
|
n -= 1 if n && n > 0
|
|
110
109
|
break if n == 0
|
|
@@ -113,8 +112,7 @@ module NNQ
|
|
|
113
112
|
loop do
|
|
114
113
|
body = @pull.receive
|
|
115
114
|
break if body.nil?
|
|
116
|
-
|
|
117
|
-
@push.send(out.first)
|
|
115
|
+
@push.send(body)
|
|
118
116
|
n -= 1 if n && n > 0
|
|
119
117
|
break if n == 0
|
|
120
118
|
end
|
|
@@ -130,7 +128,7 @@ module NNQ
|
|
|
130
128
|
@ctx.instance_exec(&@end_proc)
|
|
131
129
|
)
|
|
132
130
|
if out && !out.empty?
|
|
133
|
-
@push.send(
|
|
131
|
+
@push.send(out.first)
|
|
134
132
|
end
|
|
135
133
|
end
|
|
136
134
|
end
|
data/lib/nnq/cli/req_rep.rb
CHANGED
|
@@ -32,14 +32,12 @@ module NNQ
|
|
|
32
32
|
|
|
33
33
|
def request_and_receive(msg)
|
|
34
34
|
return nil if msg.empty?
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
reply_body = @sock.send_request(msg.first)
|
|
35
|
+
body = config.format == :marshal ? Marshal.dump(msg.first) : msg.first
|
|
36
|
+
reply_body = @sock.send_request(body)
|
|
38
37
|
transient_ready!
|
|
39
38
|
return nil if reply_body.nil?
|
|
40
|
-
reply =
|
|
41
|
-
|
|
42
|
-
reply
|
|
39
|
+
reply = config.format == :marshal ? Marshal.load(reply_body) : reply_body
|
|
40
|
+
[reply]
|
|
43
41
|
end
|
|
44
42
|
|
|
45
43
|
|
|
@@ -95,9 +93,8 @@ module NNQ
|
|
|
95
93
|
|
|
96
94
|
def send_reply(msg)
|
|
97
95
|
return if msg.empty?
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
@sock.send_reply(msg.first)
|
|
96
|
+
body = config.format == :marshal ? Marshal.dump(msg.first) : msg.first
|
|
97
|
+
@sock.send_reply(body)
|
|
101
98
|
transient_ready!
|
|
102
99
|
end
|
|
103
100
|
end
|
data/lib/nnq/cli/socket_setup.rb
CHANGED
|
@@ -77,6 +77,16 @@ module NNQ
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
# Wrap +sock+ with NNQ::Zstd if +mode+ is :fast or :balanced.
|
|
81
|
+
# Returns the wrapper (decorator) or +sock+ unchanged.
|
|
82
|
+
def self.maybe_wrap_zstd(sock, mode)
|
|
83
|
+
return sock unless mode
|
|
84
|
+
require "nnq/zstd"
|
|
85
|
+
level = mode == :balanced ? 3 : -3
|
|
86
|
+
NNQ::Zstd.wrap(sock, level: level)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
80
90
|
# Subscribe to prefixes on a SUB socket.
|
|
81
91
|
#
|
|
82
92
|
# Unlike ZeroMQ, nng's sub0 starts with an empty subscription set,
|
|
@@ -30,9 +30,8 @@ module NNQ
|
|
|
30
30
|
|
|
31
31
|
def survey_and_collect(msg)
|
|
32
32
|
return if msg.empty?
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@sock.send_survey(msg.first)
|
|
33
|
+
body = config.format == :marshal ? Marshal.dump(msg.first) : msg.first
|
|
34
|
+
@sock.send_survey(body)
|
|
36
35
|
transient_ready!
|
|
37
36
|
collect_replies
|
|
38
37
|
end
|
|
@@ -42,9 +41,8 @@ module NNQ
|
|
|
42
41
|
loop do
|
|
43
42
|
body = @sock.receive
|
|
44
43
|
break if body.nil?
|
|
45
|
-
reply =
|
|
46
|
-
|
|
47
|
-
output(eval_recv_expr(reply))
|
|
44
|
+
reply = config.format == :marshal ? Marshal.load(body) : body
|
|
45
|
+
output(eval_recv_expr([reply]))
|
|
48
46
|
rescue NNQ::TimedOut
|
|
49
47
|
break
|
|
50
48
|
end
|
|
@@ -102,9 +100,8 @@ module NNQ
|
|
|
102
100
|
|
|
103
101
|
def send_reply(msg)
|
|
104
102
|
return if msg.empty?
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@sock.send_reply(msg.first)
|
|
103
|
+
body = config.format == :marshal ? Marshal.dump(msg.first) : msg.first
|
|
104
|
+
@sock.send_reply(body)
|
|
108
105
|
transient_ready!
|
|
109
106
|
end
|
|
110
107
|
end
|
data/lib/nnq/cli/version.rb
CHANGED
data/lib/nnq/cli.rb
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "optparse"
|
|
4
|
+
|
|
5
|
+
# Forward-declare NNQ::Zstd::ProtocolError so the rescue clause below
|
|
6
|
+
# resolves even when compression wasn't requested and `nnq/zstd` was
|
|
7
|
+
# never required. The real class is defined in nnq-zstd; re-opening it
|
|
8
|
+
# here with the same StandardError superclass is benign.
|
|
9
|
+
module NNQ
|
|
10
|
+
module Zstd
|
|
11
|
+
class ProtocolError < StandardError; end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
4
15
|
require_relative "cli/version"
|
|
5
16
|
require_relative "cli/config"
|
|
6
17
|
require_relative "cli/cli_parser"
|
|
@@ -153,8 +164,8 @@ module NNQ
|
|
|
153
164
|
runner_class.new(config)
|
|
154
165
|
end
|
|
155
166
|
runner.call(task)
|
|
156
|
-
rescue
|
|
157
|
-
$stderr.puts "nnq: #{e.message}"
|
|
167
|
+
rescue NNQ::Zstd::ProtocolError => e
|
|
168
|
+
$stderr.puts "nnq: zstd protocol error: #{e.message}"
|
|
158
169
|
exit 1
|
|
159
170
|
rescue IO::TimeoutError, Async::TimeoutError
|
|
160
171
|
$stderr.puts "nnq: timeout" unless config.quiet
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nnq-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrik Wenger
|
|
@@ -24,37 +24,37 @@ dependencies:
|
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '0.5'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
-
name:
|
|
27
|
+
name: nnq-zstd
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
|
-
- - "
|
|
30
|
+
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '0'
|
|
32
|
+
version: '0.1'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- - "
|
|
37
|
+
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '0'
|
|
39
|
+
version: '0.1'
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
|
-
name:
|
|
41
|
+
name: msgpack
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
|
-
- - "
|
|
44
|
+
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '0
|
|
46
|
+
version: '0'
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
|
-
- - "
|
|
51
|
+
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '0
|
|
53
|
+
version: '0'
|
|
54
54
|
description: Command-line tool for sending and receiving nanomsg SP messages on any
|
|
55
55
|
NNQ socket type (REQ/REP, PUB/SUB, PUSH/PULL, PAIR). Supports Ruby eval (-e/-E),
|
|
56
56
|
script handlers (-r), the virtual `pipe` socket with optional Ractor parallelism,
|
|
57
|
-
multiple formats (ASCII, JSON Lines, msgpack, Marshal), and
|
|
57
|
+
multiple formats (ASCII, JSON Lines, msgpack, Marshal), and Zstd compression. Like
|
|
58
58
|
nngcat from libnng, but with Ruby superpowers.
|
|
59
59
|
email:
|
|
60
60
|
- paddor@gmail.com
|