omq-cli 0.12.3 → 0.14.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.
@@ -29,8 +29,15 @@ module OMQ
29
29
  compile_expr
30
30
  run_loop
31
31
  run_end_block
32
- rescue DecompressError => e
33
- @error_port.send(e.message)
32
+ rescue OMQ::SocketDeadError => error
33
+ # Socket was killed by a protocol violation on the peer side
34
+ # (see Engine#signal_fatal_error). Surface the underlying
35
+ # cause via the log stream and exit cleanly -- the Ractor
36
+ # completes, consumer threads unblock.
37
+ reason = error.cause&.message || error.message
38
+ @log_port.send("omq: #{reason}")
39
+ rescue => error
40
+ @error_port.send("#{error.class}: #{error.message}")
34
41
  ensure
35
42
  @sock&.close
36
43
  end
@@ -43,6 +50,8 @@ module OMQ
43
50
  def setup_socket
44
51
  @sock = @config.ffi ? OMQ.const_get(@socket_sym).new(backend: :ffi) : OMQ.const_get(@socket_sym).new
45
52
  OMQ::CLI::SocketSetup.apply_options(@sock, @config)
53
+ OMQ::CLI::SocketSetup.apply_recv_maxsz(@sock, @config)
54
+ OMQ::CLI::SocketSetup.apply_compression(@sock, @config, @config.type_name)
46
55
  @sock.identity = @config.identity if @config.identity
47
56
  OMQ::CLI::SocketSetup.attach_endpoints(@sock, @endpoints, verbose: 0)
48
57
  end
@@ -51,20 +60,32 @@ module OMQ
51
60
  def log_endpoints
52
61
  return unless @config.verbose >= 1
53
62
  @endpoints.each do |ep|
54
- @log_port.send(OMQ::CLI::Term.format_attach(ep.bind? ? :bind : :connect, ep.url, @config.verbose))
63
+ @log_port.send(OMQ::CLI::Term.format_attach(ep.bind? ? :bind : :connect, ep.url, @config.timestamps))
55
64
  end
56
65
  end
57
66
 
58
67
 
59
68
  def start_monitors
60
- return unless @config.verbose >= 2
61
- trace = @config.verbose >= 3
69
+ trace = @config.verbose >= 3
70
+ log_events = @config.verbose >= 2
62
71
  @sock.monitor(verbose: trace) do |event|
63
- @log_port.send(OMQ::CLI::Term.format_event(event, @config.verbose))
72
+ @log_port.send(OMQ::CLI::Term.format_event(event, @config.timestamps)) if log_events
73
+ kill_on_protocol_error(event)
64
74
  end
65
75
  end
66
76
 
67
77
 
78
+ # Mirrors BaseRunner#kill_on_protocol_error: CLI-level policy
79
+ # that protocol-level disconnects kill the socket so the
80
+ # recv loop unblocks with SocketDeadError.
81
+ def kill_on_protocol_error(event)
82
+ return unless event.type == :disconnected
83
+ error = event.detail && event.detail[:error]
84
+ return unless error.is_a?(Protocol::ZMTP::Error)
85
+ @sock.engine.signal_fatal_error(error)
86
+ end
87
+
88
+
68
89
  def wait_for_peer
69
90
  if @config.timeout
70
91
  Fiber.scheduler.with_timeout(@config.timeout) do
@@ -81,7 +102,7 @@ module OMQ
81
102
  def compile_expr
82
103
  @begin_proc, @end_proc, @eval_proc =
83
104
  OMQ::CLI::ExpressionEvaluator.compile_inside_ractor(@config.recv_expr)
84
- @fmt = OMQ::CLI::Formatter.new(@config.format, compress: @config.compress)
105
+ @fmt = OMQ::CLI::Formatter.new(@config.format)
85
106
  @ctx = Object.new
86
107
  @ctx.instance_exec(&@begin_proc) if @begin_proc
87
108
  end
@@ -106,7 +127,6 @@ module OMQ
106
127
  loop do
107
128
  parts = @sock.receive
108
129
  break if parts.nil?
109
- parts = @fmt.decompress(parts)
110
130
  if @eval_proc
111
131
  parts = normalize(
112
132
  @ctx.instance_exec(parts, &@eval_proc)
@@ -131,10 +151,9 @@ module OMQ
131
151
  loop do
132
152
  parts = @sock.receive
133
153
  break if parts.nil?
134
- parts = @fmt.decompress(parts)
135
154
  reply = compute_reply(parts)
136
155
  output(reply)
137
- @sock.send(@fmt.compress(reply))
156
+ @sock.send(reply)
138
157
  i += 1
139
158
  break if n && n > 0 && i >= n
140
159
  end
@@ -166,7 +185,7 @@ module OMQ
166
185
 
167
186
 
168
187
  def normalize(result)
169
- OMQ::CLI::ExpressionEvaluator.normalize_result(result)
188
+ OMQ::CLI::ExpressionEvaluator.normalize_result(result, format: @config.format)
170
189
  end
171
190
 
172
191
 
data/lib/omq/cli/pipe.rb CHANGED
@@ -11,9 +11,8 @@ module OMQ
11
11
 
12
12
  # @param config [Config] frozen CLI configuration
13
13
  def initialize(config)
14
- @config = config
15
- @fmt_in = Formatter.new(config.format, compress: config.compress_in || config.compress)
16
- @fmt_out = Formatter.new(config.format, compress: config.compress_out || config.compress)
14
+ @config = config
15
+ @fmt = Formatter.new(config.format)
17
16
  end
18
17
 
19
18
 
@@ -51,12 +50,16 @@ module OMQ
51
50
  @pull, @push = build_pull_push(in_eps, out_eps)
52
51
  compile_expr
53
52
  @sock = @pull # for eval instance_exec
54
- start_event_monitors if config.verbose >= 2
53
+ start_event_monitors
55
54
  wait_for_peers_with_timeout if config.timeout
56
55
  setup_sequential_transient(task)
57
56
  @sock.instance_exec(&@recv_begin_proc) if @recv_begin_proc
58
57
  sequential_message_loop(fan_out: out_eps.size > 1)
59
58
  @sock.instance_exec(&@recv_end_proc) if @recv_end_proc
59
+ rescue OMQ::SocketDeadError => error
60
+ reason = error.cause&.message || error.message
61
+ $stderr.write("omq: #{reason}\n")
62
+ exit 1
60
63
  ensure
61
64
  @pull&.close
62
65
  @push&.close
@@ -85,8 +88,11 @@ module OMQ
85
88
  push = OMQ::PUSH.new(**kwargs)
86
89
  SocketSetup.apply_options(pull, config)
87
90
  SocketSetup.apply_options(push, config)
88
- SocketSetup.attach_endpoints(pull, in_eps, verbose: config.verbose)
89
- SocketSetup.attach_endpoints(push, out_eps, verbose: config.verbose)
91
+ SocketSetup.apply_recv_maxsz(pull, config)
92
+ SocketSetup.apply_compression(pull, config, "pull")
93
+ SocketSetup.apply_compression(push, config, "push")
94
+ SocketSetup.attach_endpoints(pull, in_eps, verbose: config.verbose, timestamps: config.timestamps)
95
+ SocketSetup.attach_endpoints(push, out_eps, verbose: config.verbose, timestamps: config.timestamps)
90
96
  [pull, push]
91
97
  end
92
98
 
@@ -107,10 +113,9 @@ module OMQ
107
113
  loop do
108
114
  parts = @pull.receive
109
115
  break if parts.nil?
110
- parts = @fmt_in.decompress(parts)
111
116
  parts = eval_recv_expr(parts)
112
117
  if parts && !parts.empty?
113
- @push.send(@fmt_out.compress(parts))
118
+ @push.send(parts)
114
119
  end
115
120
  # Yield after send so send-pump fibers can drain the queue
116
121
  # before the next message is enqueued. Without this, one pump
@@ -163,7 +168,7 @@ module OMQ
163
168
  def set_pipe_process_title
164
169
  in_eps, out_eps = resolve_endpoints
165
170
  title = ["omq pipe"]
166
- title << "-z" if config.compress || config.compress_in || config.compress_out
171
+ title << "-z" if config.compress
167
172
  title << "-P#{config.parallel}" if config.parallel
168
173
  title.concat(in_eps.map(&:url))
169
174
  title << "->"
@@ -193,13 +198,23 @@ module OMQ
193
198
 
194
199
 
195
200
  def start_event_monitors
196
- trace = config.verbose >= 3
201
+ trace = config.verbose >= 3
202
+ log_events = config.verbose >= 2
197
203
  [@pull, @push].each do |sock|
198
204
  sock.monitor(verbose: trace) do |event|
199
- Term.write_event(event, config.verbose)
205
+ Term.write_event(event, config.timestamps) if log_events
206
+ kill_on_protocol_error(sock, event)
200
207
  end
201
208
  end
202
209
  end
210
+
211
+
212
+ def kill_on_protocol_error(sock, event)
213
+ return unless event.type == :disconnected
214
+ error = event.detail && event.detail[:error]
215
+ return unless error.is_a?(Protocol::ZMTP::Error)
216
+ sock.engine.signal_fatal_error(error)
217
+ end
203
218
  end
204
219
  end
205
220
  end
@@ -19,13 +19,14 @@ module OMQ
19
19
  Async do
20
20
  setup_sockets
21
21
  log_endpoints if @config.verbose >= 1
22
- start_monitors if @config.verbose >= 2
22
+ start_monitors
23
23
  wait_for_peers_with_timeout if @config.timeout
24
24
  compile_expr
25
25
  run_message_loop
26
26
  run_end_block
27
- rescue OMQ::CLI::DecompressError => e
28
- @error_port&.send(e.message)
27
+ rescue OMQ::SocketDeadError => error
28
+ reason = error.cause&.message || error.message
29
+ @log_port.send("omq: #{reason}")
29
30
  ensure
30
31
  @pull&.close
31
32
  @push&.close
@@ -42,6 +43,9 @@ module OMQ
42
43
  @push = OMQ::PUSH.new(**kwargs)
43
44
  OMQ::CLI::SocketSetup.apply_options(@pull, @config)
44
45
  OMQ::CLI::SocketSetup.apply_options(@push, @config)
46
+ OMQ::CLI::SocketSetup.apply_recv_maxsz(@pull, @config)
47
+ OMQ::CLI::SocketSetup.apply_compression(@pull, @config, "pull")
48
+ OMQ::CLI::SocketSetup.apply_compression(@push, @config, "push")
45
49
  OMQ::CLI::SocketSetup.attach_endpoints(@pull, @in_eps, verbose: 0)
46
50
  OMQ::CLI::SocketSetup.attach_endpoints(@push, @out_eps, verbose: 0)
47
51
  end
@@ -49,21 +53,31 @@ module OMQ
49
53
 
50
54
  def log_endpoints
51
55
  (@in_eps + @out_eps).each do |ep|
52
- @log_port.send(OMQ::CLI::Term.format_attach(ep.bind? ? :bind : :connect, ep.url, @config.verbose))
56
+ @log_port.send(OMQ::CLI::Term.format_attach(ep.bind? ? :bind : :connect, ep.url, @config.timestamps))
53
57
  end
54
58
  end
55
59
 
56
60
 
57
61
  def start_monitors
58
- trace = @config.verbose >= 3
62
+ trace = @config.verbose >= 3
63
+ log_events = @config.verbose >= 2
59
64
  [@pull, @push].each do |sock|
60
65
  sock.monitor(verbose: trace) do |event|
61
- @log_port.send(OMQ::CLI::Term.format_event(event, @config.verbose))
66
+ @log_port.send(OMQ::CLI::Term.format_event(event, @config.timestamps)) if log_events
67
+ kill_on_protocol_error(sock, event)
62
68
  end
63
69
  end
64
70
  end
65
71
 
66
72
 
73
+ def kill_on_protocol_error(sock, event)
74
+ return unless event.type == :disconnected
75
+ error = event.detail && event.detail[:error]
76
+ return unless error.is_a?(Protocol::ZMTP::Error)
77
+ sock.engine.signal_fatal_error(error)
78
+ end
79
+
80
+
67
81
  # With --timeout set, fail fast if peers never show up. Without
68
82
  # it, there's no point waiting: PULL#receive blocks naturally
69
83
  # and PUSH buffers up to send_hwm when no peer is present.
@@ -80,8 +94,7 @@ module OMQ
80
94
  def compile_expr
81
95
  @begin_proc, @end_proc, @eval_proc =
82
96
  OMQ::CLI::ExpressionEvaluator.compile_inside_ractor(@config.recv_expr)
83
- @fmt_in = OMQ::CLI::Formatter.new(@config.format, compress: @config.compress_in || @config.compress)
84
- @fmt_out = OMQ::CLI::Formatter.new(@config.format, compress: @config.compress_out || @config.compress)
97
+ @fmt = OMQ::CLI::Formatter.new(@config.format)
85
98
  @ctx = Object.new
86
99
  @ctx.instance_exec(&@begin_proc) if @begin_proc
87
100
  end
@@ -91,39 +104,15 @@ module OMQ
91
104
  n = @config.count
92
105
  if @eval_proc
93
106
  if n && n > 0
94
- n.times do
95
- parts = @pull.receive
96
- break if parts.nil?
97
- parts = OMQ::CLI::ExpressionEvaluator.normalize_result(
98
- @ctx.instance_exec(@fmt_in.decompress(parts), &@eval_proc)
99
- )
100
- next if parts.nil?
101
- @push << @fmt_out.compress(parts) unless parts.empty?
102
- end
107
+ n.times { break unless process_one_eval }
103
108
  else
104
- loop do
105
- parts = @pull.receive
106
- break if parts.nil?
107
- parts = OMQ::CLI::ExpressionEvaluator.normalize_result(
108
- @ctx.instance_exec(@fmt_in.decompress(parts), &@eval_proc)
109
- )
110
- next if parts.nil?
111
- @push << @fmt_out.compress(parts) unless parts.empty?
112
- end
109
+ loop { break unless process_one_eval }
113
110
  end
114
111
  else
115
112
  if n && n > 0
116
- n.times do
117
- parts = @pull.receive
118
- break if parts.nil?
119
- @push << @fmt_out.compress(@fmt_in.decompress(parts))
120
- end
113
+ n.times { break unless process_one_passthrough }
121
114
  else
122
- loop do
123
- parts = @pull.receive
124
- break if parts.nil?
125
- @push << @fmt_out.compress(@fmt_in.decompress(parts))
126
- end
115
+ loop { break unless process_one_passthrough }
127
116
  end
128
117
  end
129
118
  rescue IO::TimeoutError, Async::TimeoutError
@@ -131,12 +120,32 @@ module OMQ
131
120
  end
132
121
 
133
122
 
123
+ def process_one_eval
124
+ parts_in = @pull.receive
125
+ return false if parts_in.nil?
126
+ parts_out = OMQ::CLI::ExpressionEvaluator.normalize_result(
127
+ @ctx.instance_exec(parts_in, &@eval_proc), format: @config.format
128
+ )
129
+ return true if parts_out.nil? || parts_out.empty?
130
+ @push << parts_out
131
+ true
132
+ end
133
+
134
+
135
+ def process_one_passthrough
136
+ parts_in = @pull.receive
137
+ return false if parts_in.nil?
138
+ @push << parts_in
139
+ true
140
+ end
141
+
142
+
134
143
  def run_end_block
135
144
  return unless @end_proc
136
145
  out = OMQ::CLI::ExpressionEvaluator.normalize_result(
137
- @ctx.instance_exec(&@end_proc)
146
+ @ctx.instance_exec(&@end_proc), format: @config.format
138
147
  )
139
- @push << @fmt_out.compress(out) if out && !out.empty?
148
+ @push << out if out && !out.empty?
140
149
  end
141
150
  end
142
151
  end
@@ -13,7 +13,6 @@ module OMQ
13
13
  def send_msg(parts)
14
14
  return if parts.empty?
15
15
  parts = [Marshal.dump(parts)] if config.format == :marshal
16
- parts = @fmt.compress(parts)
17
16
  group = config.group || parts.shift
18
17
  @sock.publish(group, parts.first || "")
19
18
  transient_ready!
@@ -25,7 +25,6 @@ module OMQ
25
25
  break if parts.nil?
26
26
  identity = parts.shift
27
27
  parts.shift if parts.first == ""
28
- parts = @fmt.decompress(parts)
29
28
  result = eval_recv_expr([display_routing_id(identity), *parts])
30
29
  output(result)
31
30
  i += 1
@@ -36,7 +35,7 @@ module OMQ
36
35
 
37
36
 
38
37
  def send_to_peer(id, parts)
39
- @sock.send([id, "", *@fmt.compress(parts)])
38
+ @sock.send([id, "", *parts])
40
39
  end
41
40
  end
42
41
  end
@@ -22,6 +22,40 @@ module OMQ
22
22
  # it entirely with --recv-maxsz 0.
23
23
  DEFAULT_RECV_MAXSZ = 1 << 20
24
24
 
25
+ # Socket types that never receive application data. These opt
26
+ # out of the default passive-compression behavior -- they would
27
+ # otherwise advertise a profile and wrap every outgoing frame in
28
+ # a 4-byte uncompressed sentinel for no benefit, since there's
29
+ # nothing to decompress in return.
30
+ PURE_SEND_TYPES = %w[push pub scatter radio].freeze
31
+
32
+
33
+ # Installs ZMTP-Zstd compression on +sock+ based on +type_name+
34
+ # and the explicit flags in +config+. Three outcomes:
35
+ #
36
+ # * +config.compress+ is true --> active compression (auto-dict).
37
+ # Outgoing frames are compressed; incoming are decoded.
38
+ # * +config.compress+ is false and +type_name+ can receive -->
39
+ # passive compression (RFC Sec. 6.4). The socket advertises the
40
+ # profile so an active peer can compress on the wire and we can
41
+ # decode it, but we never compress our own outgoing frames.
42
+ # * +config.compress+ is false and +type_name+ is in
43
+ # +PURE_SEND_TYPES+ --> no compression. Pure senders have no
44
+ # incoming traffic to decompress, so passive mode is pure
45
+ # overhead on outgoing.
46
+ #
47
+ # Callers pass +type_name+ explicitly (rather than reading it off
48
+ # +config+) so the pipe runners can install different modes on
49
+ # their push/pull ends of a single pipe.
50
+ def self.apply_compression(sock, config, type_name)
51
+ if config.compress
52
+ sock.compression = OMQ::RFC::Zstd::Compression.auto(level: config.compress_level || -3)
53
+ elsif !PURE_SEND_TYPES.include?(type_name)
54
+ sock.compression = OMQ::RFC::Zstd::Compression.auto(passive: true)
55
+ end
56
+ end
57
+
58
+
25
59
  # Apply common socket options from +config+ to +sock+.
26
60
  #
27
61
  def self.apply_options(sock, config)
@@ -44,46 +78,52 @@ module OMQ
44
78
  sock = config.ffi ? klass.new(backend: :ffi) : klass.new
45
79
  sock.conflate = true if config.conflate && %w[pub radio].include?(config.type_name)
46
80
  apply_options(sock, config)
47
- # --recv-maxsz: nil → 1 MiB default; 0 → explicitly unlimited; else → as-is.
81
+ apply_recv_maxsz(sock, config)
82
+ sock.identity = config.identity if config.identity
83
+ sock.router_mandatory = true if config.type_name == "router"
84
+ apply_compression(sock, config, config.type_name)
85
+ sock
86
+ end
87
+
88
+
89
+ # --recv-maxsz: nil → 1 MiB default; 0 → explicitly unlimited; else → as-is.
90
+ def self.apply_recv_maxsz(sock, config)
48
91
  sock.max_message_size =
49
92
  case config.recv_maxsz
50
93
  when nil then DEFAULT_RECV_MAXSZ
51
94
  when 0 then nil
52
95
  else config.recv_maxsz
53
96
  end
54
- sock.identity = config.identity if config.identity
55
- sock.router_mandatory = true if config.type_name == "router"
56
- sock
57
97
  end
58
98
 
59
99
 
60
100
  # Bind/connect +sock+ using URL strings from +config.binds+ / +config.connects+.
61
- # +verbose+ is the integer verbosity level (0 = silent).
101
+ # +verbose+ gates logging (>= 1), +timestamps+ controls prefix.
62
102
  #
63
- def self.attach(sock, config, verbose: 0)
103
+ def self.attach(sock, config, verbose: 0, timestamps: nil)
64
104
  config.binds.each do |url|
65
105
  sock.bind(url)
66
- CLI::Term.write_attach(:bind, sock.last_endpoint, verbose) if verbose >= 1
106
+ CLI::Term.write_attach(:bind, sock.last_endpoint, timestamps) if verbose >= 1
67
107
  end
68
108
  config.connects.each do |url|
69
109
  sock.connect(url)
70
- CLI::Term.write_attach(:connect, url, verbose) if verbose >= 1
110
+ CLI::Term.write_attach(:connect, url, timestamps) if verbose >= 1
71
111
  end
72
112
  end
73
113
 
74
114
 
75
115
  # Bind/connect +sock+ from an Array of Endpoint objects.
76
116
  # Used by PipeRunner, which works with structured endpoint lists.
77
- # +verbose+ is the integer verbosity level (0 = silent).
117
+ # +verbose+ gates logging (>= 1), +timestamps+ controls prefix.
78
118
  #
79
- def self.attach_endpoints(sock, endpoints, verbose: 0)
119
+ def self.attach_endpoints(sock, endpoints, verbose: 0, timestamps: nil)
80
120
  endpoints.each do |ep|
81
121
  if ep.bind?
82
122
  sock.bind(ep.url)
83
- CLI::Term.write_attach(:bind, sock.last_endpoint, verbose) if verbose >= 1
123
+ CLI::Term.write_attach(:bind, sock.last_endpoint, timestamps) if verbose >= 1
84
124
  else
85
125
  sock.connect(ep.url)
86
- CLI::Term.write_attach(:connect, ep.url, verbose) if verbose >= 1
126
+ CLI::Term.write_attach(:connect, ep.url, timestamps) if verbose >= 1
87
127
  end
88
128
  end
89
129
  end
data/lib/omq/cli/term.rb CHANGED
@@ -15,15 +15,18 @@ module OMQ
15
15
  module_function
16
16
 
17
17
 
18
- # Returns a stderr log line prefix. At verbose >= 4, prepends an
19
- # ISO8601 UTC timestamp with µs precision so log traces become
20
- # time-correlatable. Otherwise returns the empty string.
18
+ # Returns a stderr log line prefix with a UTC ISO8601 timestamp
19
+ # at the requested precision (:s/:ms/:us), or "" when nil.
21
20
  #
22
- # @param verbose [Integer]
21
+ # @param timestamps [Symbol, nil] :s, :ms, :us, or nil (disabled)
23
22
  # @return [String]
24
- def log_prefix(verbose)
25
- return "" unless verbose && verbose >= 4
26
- "#{Time.now.utc.strftime("%FT%T.%6N")}Z "
23
+ def log_prefix(timestamps)
24
+ case timestamps
25
+ when nil then ""
26
+ when :s then "#{Time.now.utc.strftime("%FT%T")}Z "
27
+ when :ms then "#{Time.now.utc.strftime("%FT%T.%3N")}Z "
28
+ when :us then "#{Time.now.utc.strftime("%FT%T.%6N")}Z "
29
+ end
27
30
  end
28
31
 
29
32
 
@@ -31,18 +34,29 @@ module OMQ
31
34
  # trailing newline).
32
35
  #
33
36
  # @param event [OMQ::MonitorEvent]
34
- # @param verbose [Integer]
37
+ # @param timestamps [Symbol, nil]
35
38
  # @return [String]
36
- def format_event(event, verbose)
37
- prefix = log_prefix(verbose)
39
+ def format_event(event, timestamps)
40
+ prefix = log_prefix(timestamps)
38
41
  case event.type
39
42
  when :message_sent
40
- "#{prefix}omq: >> #{Formatter.preview(event.detail[:parts])}"
43
+ "#{prefix}omq: >> #{Formatter.preview(event.detail[:parts], wire_size: event.detail[:wire_size])}"
41
44
  when :message_received
42
- "#{prefix}omq: << #{Formatter.preview(event.detail[:parts])}"
45
+ "#{prefix}omq: << #{Formatter.preview(event.detail[:parts], wire_size: event.detail[:wire_size])}"
46
+ when :zdict_sent
47
+ "#{prefix}omq: >> ZDICT (#{event.detail[:size]}B)"
48
+ when :zdict_received
49
+ "#{prefix}omq: << ZDICT (#{event.detail[:size]}B)"
43
50
  else
44
51
  ep = event.endpoint ? " #{event.endpoint}" : ""
45
- detail = event.detail ? " #{event.detail}" : ""
52
+ detail =
53
+ if event.detail.is_a?(Hash) && event.detail[:reason]
54
+ " (#{event.detail[:reason]})"
55
+ elsif event.detail
56
+ " #{event.detail}"
57
+ else
58
+ ""
59
+ end
46
60
  "#{prefix}omq: #{event.type}#{ep}#{detail}"
47
61
  end
48
62
  end
@@ -52,22 +66,22 @@ module OMQ
52
66
  #
53
67
  # @param kind [:bind, :connect]
54
68
  # @param url [String]
55
- # @param verbose [Integer]
69
+ # @param timestamps [Symbol, nil]
56
70
  # @return [String]
57
- def format_attach(kind, url, verbose)
71
+ def format_attach(kind, url, timestamps)
58
72
  verb = kind == :bind ? "Bound to" : "Connecting to"
59
- "#{log_prefix(verbose)}omq: #{verb} #{url}"
73
+ "#{log_prefix(timestamps)}omq: #{verb} #{url}"
60
74
  end
61
75
 
62
76
 
63
77
  # Writes one formatted event line to +io+ (default $stderr).
64
78
  #
65
79
  # @param event [OMQ::MonitorEvent]
66
- # @param verbose [Integer]
80
+ # @param timestamps [Symbol, nil]
67
81
  # @param io [#write] writable sink, default $stderr
68
82
  # @return [void]
69
- def write_event(event, verbose, io: $stderr)
70
- io.write("#{format_event(event, verbose)}\n")
83
+ def write_event(event, timestamps, io: $stderr)
84
+ io.write("#{format_event(event, timestamps)}\n")
71
85
  end
72
86
 
73
87
 
@@ -76,11 +90,11 @@ module OMQ
76
90
  #
77
91
  # @param kind [:bind, :connect]
78
92
  # @param url [String]
79
- # @param verbose [Integer]
93
+ # @param timestamps [Symbol, nil]
80
94
  # @param io [#write]
81
95
  # @return [void]
82
- def write_attach(kind, url, verbose, io: $stderr)
83
- io.write("#{format_attach(kind, url, verbose)}\n")
96
+ def write_attach(kind, url, timestamps, io: $stderr)
97
+ io.write("#{format_attach(kind, url, timestamps)}\n")
84
98
  end
85
99
  end
86
100
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OMQ
4
4
  module CLI
5
- VERSION = "0.12.3"
5
+ VERSION = "0.14.0"
6
6
  end
7
7
  end
data/lib/omq/cli.rb CHANGED
@@ -197,6 +197,7 @@ module OMQ
197
197
  require "omq/rfc/scattergather"
198
198
  require "omq/rfc/channel"
199
199
  require "omq/rfc/p2p"
200
+ require "omq/rfc/zstd"
200
201
  require "async"
201
202
  require "json"
202
203
  require "console"
@@ -247,9 +248,6 @@ module OMQ
247
248
  runner_class.new(config)
248
249
  end
249
250
  runner.call(task)
250
- rescue DecompressError => e
251
- $stderr.puts "omq: #{e.message}"
252
- exit 1
253
251
  rescue IO::TimeoutError, Async::TimeoutError
254
252
  $stderr.puts "omq: timeout" unless config.quiet
255
253
  exit 2