march_hare 3.1.1-java → 4.3.0-java

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: 910cb519cfde61ec8390a0c56db3121eb8e5675a3c5b19d662db8ad9a3f7a8d7
4
- data.tar.gz: 0be92a42c7ea2102c442184d0cc892fb171a83f59a718fc1411514f51b5c4dae
3
+ metadata.gz: 006ea49a052e4f2995f87e2739eacfd552945f61135ba8b329cd8dcdf36ede45
4
+ data.tar.gz: 5ef91217f326fb9cca331378adaae5684a4e98d0b70748b4fd04227c95ccfc74
5
5
  SHA512:
6
- metadata.gz: 2224b9d612f2419772a19cee956a433243b9e76a3807c372cca723591ee338ab9a2dfa9353e7bbe25601337189b9ab5468ffde8217e7142442baee97b66f082c
7
- data.tar.gz: f592e103fcb40342e7162cbb9a10808267eeb435b017438ebf9590745684903018ddd1a5aad6d0f80ca4d59b1a85b6b34bfe18c0fe716b2eb0ef2b12843c4d40
6
+ metadata.gz: 121e50ac297e48dd61a08f6b08a81e85782bf6dfe402d48320f2654daa4f3cfbbfc3a76c69a61114a7add12ccbe771bcfd7115b4c47cba65fb13cc4bebc32b70
7
+ data.tar.gz: 2fcaa00100551f6d6a3fd4005722e168684598c612279668f5c82e324848156722d69e2b86a3a7f2efb5cbabeae8de19546ea94ddb5bfa0a9167e594bbaabf2d
Binary file
Binary file
Binary file
@@ -144,6 +144,11 @@ module MarchHare
144
144
  alias client session
145
145
  alias connection session
146
146
 
147
+ # @return [::Logger] Logger instance from the connection
148
+ def logger
149
+ @connection.logger
150
+ end
151
+
147
152
  # @return [Integer] Channel id
148
153
  def channel_number
149
154
  @delegate.channel_number
@@ -187,6 +192,8 @@ module MarchHare
187
192
 
188
193
  # @private
189
194
  def automatically_recover(session, java_connection)
195
+ logger.debug("channel: begin automatic connection recovery")
196
+
190
197
  jch = java_connection.create_channel(id)
191
198
 
192
199
  self.revive_with(jch)
@@ -247,10 +254,11 @@ module MarchHare
247
254
  def recover_exchanges
248
255
  @exchanges.values.each do |x|
249
256
  begin
257
+ logger.debug("channel: recover exchange #{x.name}")
250
258
  x.recover_from_network_failure
251
259
  rescue Exception => e
252
- # TODO: logger
253
- $stderr.puts "Caught exception when recovering exchange #{x.name}"
260
+ logger.error("Caught exception when recovering exchange #{x.name}")
261
+ logger.error(e)
254
262
  end
255
263
  end
256
264
  end
@@ -260,10 +268,11 @@ module MarchHare
260
268
  def recover_queues
261
269
  @queues.values.each do |q|
262
270
  begin
271
+ logger.debug("channel: recover queue #{q.name}")
263
272
  q.recover_from_network_failure
264
273
  rescue Exception => e
265
- # TODO: logger
266
- $stderr.puts "Caught exception when recovering queue #{q.name}"
274
+ logger.error("Caught exception when recovering queue #{q.name}")
275
+ logger.error(e)
267
276
  end
268
277
  end
269
278
  end
@@ -273,11 +282,12 @@ module MarchHare
273
282
  def recover_consumers
274
283
  @consumers.values.each do |c|
275
284
  begin
285
+ logger.debug("channel: recover consumer #{c.consumer_tag}")
276
286
  self.unregister_consumer(c.consumer_tag)
277
287
  c.recover_from_network_failure
278
288
  rescue Exception => e
279
- # TODO: logger
280
- $stderr.puts "Caught exception when recovering consumer #{c.consumer_tag}"
289
+ logger.error("Caught exception when recovering consumer #{c.consumer_tag}")
290
+ logger.error(e)
281
291
  end
282
292
  end
283
293
  end
@@ -924,6 +934,7 @@ module MarchHare
924
934
 
925
935
  # @private
926
936
  def deregister_queue(queue)
937
+ logger.debug("channel: deregister queue #{queue.name}")
927
938
  @queues.delete(queue.name)
928
939
  end
929
940
 
@@ -934,6 +945,7 @@ module MarchHare
934
945
 
935
946
  # @private
936
947
  def register_queue(queue)
948
+ logger.debug("channel: register queue #{queue.name}")
937
949
  @queues[queue.name] = queue
938
950
  end
939
951
 
@@ -944,21 +956,25 @@ module MarchHare
944
956
 
945
957
  # @private
946
958
  def deregister_exchange(exchange)
959
+ logger.debug("channel: deregister exchange #{exchange.name}")
947
960
  @exchanges.delete(exchange.name)
948
961
  end
949
962
 
950
963
  # @private
951
964
  def register_exchange(exchange)
965
+ logger.debug("channel: register exchange #{exchange.name}")
952
966
  @exchanges[exchange.name] = exchange
953
967
  end
954
968
 
955
969
  # @private
956
970
  def register_consumer(consumer_tag, consumer)
971
+ logger.debug("channel: register consumer #{consumer_tag}")
957
972
  @consumers[consumer_tag] = consumer
958
973
  end
959
974
 
960
975
  # @private
961
976
  def unregister_consumer(consumer_tag)
977
+ logger.debug("channel: unregister consumer #{consumer_tag}")
962
978
  @consumers.delete(consumer_tag)
963
979
  end
964
980
 
@@ -0,0 +1,17 @@
1
+ module MarchHare
2
+ class ExceptionHandler < com.rabbitmq.client.impl.ForgivingExceptionHandler
3
+ def initialize(logger)
4
+ super()
5
+ @logger = logger
6
+ end
7
+
8
+ def log(msg, error)
9
+ logger.error(msg)
10
+ logger.error(error)
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :logger
16
+ end
17
+ end
@@ -16,6 +16,12 @@ module MarchHare
16
16
  class ConnectionRefused < NetworkException
17
17
  end
18
18
 
19
+ class ConnectionClosedException < Exception
20
+ def initialize(message='')
21
+ super("Connection was explicitly closed and cannot be reopened. Create a new Connection instead. #{message}")
22
+ end
23
+ end
24
+
19
25
  class ChannelLevelException < Exception
20
26
  attr_reader :channel_close
21
27
 
@@ -99,14 +105,14 @@ module MarchHare
99
105
  def self.convert(e, unwrap_io_exception = true)
100
106
  case e
101
107
  when java.net.SocketException then
102
- IOError.new
108
+ IOError.new(e.message)
103
109
  when java.io.IOException then
104
110
  c = e.cause
105
111
 
106
112
  if c && unwrap_io_exception
107
113
  convert(c, false)
108
114
  else
109
- IOError.new
115
+ IOError.new(e.message)
110
116
  end
111
117
  when com.rabbitmq.client.AlreadyClosedException then
112
118
  ChannelAlreadyClosed.new(e.reason)
@@ -193,8 +193,8 @@ module MarchHare
193
193
 
194
194
  @channel.register_exchange(self)
195
195
  rescue Exception => e
196
- # TODO: use a logger
197
- puts "Caught #{e.inspect} while redeclaring and registering exchange #{@name}!"
196
+ @channel.logger.error("Caught Exception while redeclaring and registering exchange #{@name}!")
197
+ @channel.logger.error(e)
198
198
  end
199
199
  end
200
200
  end
@@ -168,7 +168,6 @@ module MarchHare
168
168
  #
169
169
  # @option opts [Boolean] :manual_ack (false) Will this consumer use manual acknowledgements?
170
170
  # @option opts [Boolean] :exclusive (false) Should this consumer be exclusive for this queue?
171
- # @option opts [Boolean] :block (false) Should the call block calling thread?
172
171
  # @option opts [#call] :on_cancellation Block to execute when this consumer is cancelled remotely (e.g. via the RabbitMQ Management plugin)
173
172
  # @option opts [String] :consumer_tag Unique consumer identifier. It is usually recommended to let MarchHare generate it for you.
174
173
  # @option opts [Hash] :arguments ({}) Additional (optional) arguments, typically used by RabbitMQ extensions
@@ -233,6 +232,7 @@ module MarchHare
233
232
 
234
233
  # @private
235
234
  def declare!
235
+ @channel.logger.debug("queue: declare! #{@name}")
236
236
  response = if @options[:passive]
237
237
  then @channel.queue_declare_passive(@name)
238
238
  else @channel.queue_declare(@name, @options[:durable], @options[:exclusive], @options[:auto_delete], @options[:arguments])
@@ -258,8 +258,7 @@ module MarchHare
258
258
  # @private
259
259
  def recover_bindings
260
260
  @bindings.each do |b|
261
- # TODO: use a logger
262
- # puts "Recovering binding #{b.inspect}"
261
+ @channel.logger.debug("Recovering binding #{b.inspect}")
263
262
  self.bind(b[:exchange], b)
264
263
  end
265
264
  end
@@ -2,13 +2,15 @@
2
2
  require "march_hare/shutdown_listener"
3
3
  require "set"
4
4
  require "march_hare/thread_pools"
5
+ require "march_hare/exception_handler"
5
6
  require "java"
7
+ require "logger"
6
8
 
7
9
  module MarchHare
8
10
  java_import com.rabbitmq.client.ConnectionFactory
9
11
  java_import com.rabbitmq.client.Connection
10
12
  java_import com.rabbitmq.client.BlockedListener
11
- java_import com.rabbitmq.client.NullTrustManager
13
+ java_import com.rabbitmq.client.TrustEverythingTrustManager
12
14
  java_import com.rabbitmq.client.MissedHeartbeatException
13
15
  java_import com.rabbitmq.client.Address
14
16
 
@@ -52,6 +54,9 @@ module MarchHare
52
54
  # This will switch port to 5671 by default.
53
55
  # @option options [String] :tls_certificate_path Path to a PKCS12 certificate.
54
56
  # @option options [java.util.concurrent.ThreadFactory] :thread_factory Thread factory RabbitMQ Java client will use (useful in restricted PaaS platforms such as GAE)
57
+ # @option options [Logger] :logger The logger. If missing, one is created using :log_file and :log_level.
58
+ # @option options [IO, String] :log_file The file or path to use when creating a logger. Defaults to STDOUT.
59
+ # @option options [Integer] :log_level The log level to use when creating a logger. Defaults to LOGGER::WARN
55
60
  #
56
61
  # @see http://rubymarchhare.info/articles/connecting.html Connecting to RabbitMQ guide
57
62
  def self.connect(options = {})
@@ -77,17 +82,16 @@ module MarchHare
77
82
  cf.connection_timeout = connection_timeout_from(options) if include_connection_timeout?(options)
78
83
 
79
84
  cf.thread_factory = thread_factory_from(options) if include_thread_factory?(options)
80
- cf.exception_handler = exception_handler_from(options) if include_exception_handler?(options)
81
85
 
82
86
  tls = (options[:ssl] || options[:tls])
83
87
  case tls
84
88
  when true then
85
89
  cf.use_ssl_protocol
86
- when String then
87
- # TODO: logging
88
- $stdout.puts "Using TLS/SSL version #{tls}"
89
- # Note: `options[:trust_manager] = com.rabbitmq.client.NullTrustManager.new` can be set to disable TLS verification.
90
- if (cert_path = tls_certificate_path_from(options)) && (password = tls_certificate_password_from(options))
90
+ when String then
91
+ options[:logger].info("Using TLS/SSL version #{tls}") if options[:logger]
92
+ # Note: `options[:trust_manager] = com.rabbitmq.client.TrustEverythingTrustManager.new`
93
+ # can be set to effectively disable TLS verification.
94
+ if (cert_path = tls_certificate_path_from(options)) && (password = tls_certificate_password_from(options))
91
95
  ctx = SSLContext.get_instance(tls)
92
96
  pwd = password.to_java.to_char_array
93
97
  begin
@@ -99,7 +103,7 @@ module MarchHare
99
103
  kmf.init(ks, pwd)
100
104
 
101
105
  if options[:trust_manager]
102
- ctx.init(kmf.get_key_managers, [options[:trust_manager]], nil)
106
+ ctx.init(kmf.get_key_managers, Array(options[:trust_manager]), nil)
103
107
  else
104
108
  # use the key store as the trust store
105
109
  tmf = TrustManagerFactory.get_instance(TrustManagerFactory.getDefaultAlgorithm());
@@ -107,6 +111,7 @@ module MarchHare
107
111
  ctx.init(kmf.get_key_managers, tmf.getTrustManagers(), nil)
108
112
  end
109
113
 
114
+ cf.set_sasl_config(options[:sasl_config]) if options[:sasl_config]
110
115
  cf.use_ssl_protocol(ctx)
111
116
  rescue Java::JavaLang::Throwable => e
112
117
  message = e.message
@@ -134,11 +139,19 @@ module MarchHare
134
139
  # @return [Array<MarchHare::Channel>] Channels opened on this connection
135
140
  attr_reader :channels
136
141
 
142
+ # @return [::Logger] Logger instance
143
+ attr_reader :logger
144
+
137
145
 
138
146
  # @private
139
147
  def initialize(connection_factory, opts = {})
140
148
  @cf = connection_factory
141
149
 
150
+ log_file = opts[:log_file] || STDOUT
151
+ log_level = opts[:log_level] || ENV["MARCH_HARE_LOG_LEVEL"] || Logger::WARN
152
+ @logger = opts.fetch(:logger, init_default_logger(log_file, log_level))
153
+ @cf.exception_handler = opts.fetch(:exception_handler, init_default_exception_handler(@logger))
154
+
142
155
  # March Hare uses its own connection recovery implementation and
143
156
  # as of Java client 4.x automatic recovery is enabled by
144
157
  # default. MK.
@@ -153,7 +166,7 @@ module MarchHare
153
166
  # we expect this option to be specified in seconds
154
167
  @executor_shutdown_timeout = opts.fetch(:executor_shutdown_timeout, 30.0)
155
168
 
156
- @addresses = self.class.adresses_from(opts)
169
+ @addresses = self.class.addresses_from(opts)
157
170
  @connection = build_new_connection
158
171
  @channels = JavaConcurrent::ConcurrentHashMap.new
159
172
 
@@ -165,6 +178,9 @@ module MarchHare
165
178
  end
166
179
  @network_recovery_interval = opts.fetch(:network_recovery_interval, DEFAULT_NETWORK_RECOVERY_INTERVAL)
167
180
  @shutdown_hooks = Array.new
181
+ @blocked_connection_hooks = Array.new
182
+ @connection_recovery_hooks = Array.new
183
+ @was_explicitly_closed = false
168
184
 
169
185
  if @automatically_recover
170
186
  self.add_automatic_recovery_hook
@@ -210,8 +226,16 @@ module MarchHare
210
226
  ch.close
211
227
  end
212
228
 
229
+ @was_explicitly_closed = true
213
230
  maybe_shut_down_executor
214
231
  @connection.close
232
+ rescue com.rabbitmq.client.AlreadyClosedException
233
+ @logger.debug("close: connection already closed")
234
+ end
235
+
236
+ def reopen
237
+ @was_explicitly_closed = false
238
+ automatically_recover
215
239
  end
216
240
 
217
241
  # @return [Boolean] true if connection is open, false otherwise
@@ -239,19 +263,45 @@ module MarchHare
239
263
 
240
264
  # Defines a connection.blocked handler
241
265
  def on_blocked(&block)
242
- self.add_blocked_listener(BlockBlockedUnblockedListener.for_blocked(block))
266
+ listener = BlockBlockedUnblockedListener.for_blocked(block)
267
+ @blocked_connection_hooks << listener
268
+
269
+ self.add_blocked_listener(listener)
243
270
  end
244
271
 
245
272
  # Defines a connection.unblocked handler
246
273
  def on_unblocked(&block)
247
- self.add_blocked_listener(BlockBlockedUnblockedListener.for_unblocked(block))
274
+ listener = BlockBlockedUnblockedListener.for_unblocked(block)
275
+ @blocked_connection_hooks << listener
276
+
277
+ self.add_blocked_listener(listener)
278
+ end
279
+
280
+ def add_blocked_listener(listener)
281
+ @connection.add_blocked_listener(listener)
248
282
  end
249
283
 
250
284
  # Clears all callbacks defined with #on_blocked and #on_unblocked.
251
285
  def clear_blocked_connection_callbacks
286
+ @blocked_connection_hooks.clear
287
+
252
288
  @connection.clear_blocked_listeners
253
289
  end
254
290
 
291
+ def on_recovery_start(&block)
292
+ listener = RecoveryListener.for_start(block)
293
+ @connection_recovery_hooks << listener
294
+ end
295
+
296
+ def on_recovery(&block)
297
+ listener = RecoveryListener.for_finish(block)
298
+ @connection_recovery_hooks << listener
299
+ end
300
+
301
+ # Clears all callbacks defined with #on_recovery_started and #on_recovery
302
+ def clear_connection_recovery_callbacks
303
+ @connection_recovery_hooks.clear
304
+ end
255
305
 
256
306
  # @private
257
307
  def add_automatic_recovery_hook
@@ -277,6 +327,11 @@ module MarchHare
277
327
  # Begins automatic connection recovery (typically only used internally
278
328
  # to recover from network failures)
279
329
  def automatically_recover
330
+ raise ConnectionClosedException if @was_explicitly_closed
331
+ @logger.debug("session: begin automatic connection recovery #{Thread.current.inspect}")
332
+
333
+ fire_recovery_start_hooks
334
+
280
335
  ms = @network_recovery_interval * 1000
281
336
  # recovering immediately makes little sense. Wait a bit first. MK.
282
337
  java.lang.Thread.sleep(ms)
@@ -285,6 +340,7 @@ module MarchHare
285
340
  reconnecting_on_network_failures(ms) { build_new_connection }
286
341
  end
287
342
  self.recover_shutdown_hooks(new_connection)
343
+ self.recover_connection_block_hooks(new_connection)
288
344
 
289
345
  # sorting channels by id means that the cases like the following:
290
346
  #
@@ -302,21 +358,33 @@ module MarchHare
302
358
  begin
303
359
  ch.automatically_recover(self, new_connection)
304
360
  rescue Exception, java.io.IOException => e
305
- # TODO: logging
306
- $stderr.puts e
361
+ @logger.error(e)
307
362
  end
308
363
  end
309
364
 
310
365
  @connection = new_connection
366
+
367
+ fire_recovery_hooks
368
+
369
+ @connection
311
370
  end
312
371
 
313
372
  # @private
314
373
  def recover_shutdown_hooks(connection)
374
+ @logger.debug("session: recover_shutdown_hooks")
315
375
  @shutdown_hooks.each do |sh|
316
376
  connection.add_shutdown_listener(sh)
317
377
  end
318
378
  end
319
379
 
380
+ # @private
381
+ def recover_connection_block_hooks(connection)
382
+ @logger.debug("session: recover_connection_block_hooks")
383
+ @blocked_connection_hooks.each do |listener|
384
+ connection.add_blocked_listener(listener)
385
+ end
386
+ end
387
+
320
388
  # Flushes the socket used by this connection.
321
389
  def flush
322
390
  @connection.flush
@@ -401,7 +469,7 @@ module MarchHare
401
469
  end
402
470
 
403
471
  # @private
404
- def self.adresses_from(options)
472
+ def self.addresses_from(options)
405
473
  options[:addresses] || options[:hosts] || [address_with_port_from(options)]
406
474
  end
407
475
 
@@ -485,13 +553,16 @@ module MarchHare
485
553
  end
486
554
 
487
555
  # @private
488
- def self.exception_handler_from(opts)
489
- opts[:exception_handler]
490
- end
491
-
492
- # @private
493
- def self.include_exception_handler?(opts)
494
- !!opts[:exception_handler]
556
+ def endpoint_info_from(cf)
557
+ if @uses_uri
558
+ uri_without_credentials = URI.parse(@uri).tap do |u|
559
+ u.password = "REDACTED"
560
+ u.to_s
561
+ end
562
+ "Target URI: #{uri_without_credentials}"
563
+ else
564
+ "Target host list: #{@addresses.join(', ')}, target virtual host: #{cf.virtual_host}, username: #{cf.username}"
565
+ end
495
566
  end
496
567
 
497
568
  # Executes a block, catching Java exceptions RabbitMQ Java client throws and
@@ -501,28 +572,30 @@ module MarchHare
501
572
  def converting_rjc_exceptions_to_ruby(&block)
502
573
  begin
503
574
  block.call
504
- rescue java.net.ConnectException => e
505
- raise ConnectionRefused.new("Connection to #{@cf.host}:#{@cf.port} refused")
506
- rescue java.net.NoRouteToHostException => e
507
- raise ConnectionRefused.new("Connection to #{@cf.host}:#{@cf.port} failed: no route to host")
508
- rescue java.net.UnknownHostException => e
509
- raise ConnectionRefused.new("Connection to #{@cf.host}:#{@cf.port} refused: host unknown")
510
- rescue java.net.SocketException => e
511
- raise ConnectionRefused.new("Connection to #{@cf.host}:#{@cf.port} failed")
512
- rescue java.util.concurrent.TimeoutException => e
513
- raise ConnectionRefused.new("Connection to #{@cf.host}:#{@cf.port} failed: timeout")
514
- rescue com.rabbitmq.client.AuthenticationFailureException => e
575
+ rescue java.net.ConnectException
576
+ raise ConnectionRefused.new("Connection was refused. #{endpoint_info_from(@cf)}")
577
+ rescue java.net.NoRouteToHostException
578
+ raise ConnectionRefused.new("Connection failed: no route to target host. #{endpoint_info_from(@cf)}")
579
+ rescue java.net.UnknownHostException
580
+ raise ConnectionRefused.new("Connection refused: target host unknown (cannot be resolved). #{endpoint_info_from(@cf)}")
581
+ rescue java.net.SocketException
582
+ raise ConnectionRefused.new("Connection failed due to a socket exception. #{endpoint_info_from(@cf)}")
583
+ rescue java.util.concurrent.TimeoutException
584
+ raise ConnectionRefused.new("Connection timed out. #{endpoint_info_from(@cf)}")
585
+ rescue com.rabbitmq.client.AuthenticationFailureException
515
586
  raise AuthenticationFailureError.new(@cf.username, @cf.virtual_host, @cf.password.bytesize)
516
- rescue com.rabbitmq.client.PossibleAuthenticationFailureException => e
587
+ rescue com.rabbitmq.client.PossibleAuthenticationFailureException
517
588
  raise PossibleAuthenticationFailureError.new(@cf.username, @cf.virtual_host, @cf.password.bytesize)
518
589
  end
519
590
  end
520
591
 
521
592
  # @private
522
593
  def reconnecting_on_network_failures(interval_in_ms, &fn)
594
+ @logger.debug("session: reconnecting_on_network_failures")
523
595
  begin
596
+ return if @was_explicitly_closed
524
597
  fn.call
525
- rescue IOError, MarchHare::ConnectionRefused, java.io.IOException, java.util.concurrent.TimeoutException => e
598
+ rescue IOError, MarchHare::ConnectionRefused, java.io.IOException, java.util.concurrent.TimeoutException
526
599
  java.lang.Thread.sleep(interval_in_ms)
527
600
 
528
601
  retry
@@ -531,7 +604,13 @@ module MarchHare
531
604
 
532
605
  # @private
533
606
  def build_new_connection
534
- @uses_uri ? new_uri_connection_impl(@uri) : new_connection_impl(@addresses)
607
+ if @uses_uri
608
+ @logger.debug("session: instantiating a new connection using a URI")
609
+ new_uri_connection_impl(@uri)
610
+ else
611
+ @logger.debug("session: instantiating a new connection using a set of addresses: #{@addresses.join(',')}")
612
+ new_connection_impl(@addresses)
613
+ end
535
614
  end
536
615
 
537
616
  # @private
@@ -608,6 +687,48 @@ module MarchHare
608
687
  self.class.tls_certificate_password_from(opts)
609
688
  end
610
689
 
690
+ # @private
691
+ def init_default_exception_handler(logger)
692
+ ExceptionHandler.new(logger)
693
+ end
694
+
695
+ # @private
696
+ def init_default_logger(logfile, level)
697
+ lgr = ::Logger.new(logfile)
698
+ lgr.level = normalize_log_level(level)
699
+ lgr.progname = self.to_s
700
+ lgr
701
+ end
702
+
703
+ # @private
704
+ def normalize_log_level(level)
705
+ case level
706
+ when :debug, Logger::DEBUG, "debug" then Logger::DEBUG
707
+ when :info, Logger::INFO, "info" then Logger::INFO
708
+ when :warn, Logger::WARN, "warn" then Logger::WARN
709
+ when :error, Logger::ERROR, "error" then Logger::ERROR
710
+ when :fatal, Logger::FATAL, "fatal" then Logger::FATAL
711
+ else
712
+ Logger::WARN
713
+ end
714
+ end
715
+
716
+ # @private
717
+ def fire_recovery_start_hooks
718
+ @logger.debug "Have #{@connection_recovery_hooks.size} recovery start hooks to run"
719
+ @connection_recovery_hooks.each do |recovery_listener|
720
+ recovery_listener.handle_recovery_started(self)
721
+ end
722
+ end
723
+
724
+ # @private
725
+ def fire_recovery_hooks
726
+ @logger.debug "Have #{@connection_recovery_hooks.size} recovery completion hooks to run"
727
+ @connection_recovery_hooks.each do |recovery_listener|
728
+ recovery_listener.handle_recovery(self)
729
+ end
730
+ end
731
+
611
732
  # Ruby blocks-based BlockedListener that handles
612
733
  # connection.blocked and connection.unblocked.
613
734
  # @private
@@ -646,5 +767,32 @@ module MarchHare
646
767
  end
647
768
  end
648
769
 
770
+ # Ruby blocks-based RecoveryListener that handles
771
+ # connection recovery_started and recovery
772
+ class RecoveryListener
773
+ NOOP_FN1 = Proc.new { |_| }
774
+ private_constant :NOOP_FN1
775
+
776
+ def self.for_start(block)
777
+ new(block, NOOP_FN1)
778
+ end
779
+
780
+ def self.for_finish(block)
781
+ new(NOOP_FN1, block)
782
+ end
783
+
784
+ def initialize(before_recovery, after_recovery)
785
+ @recovery_start_hook = before_recovery
786
+ @recovery_hook = after_recovery
787
+ end
788
+
789
+ def handle_recovery_started(recoverable)
790
+ @recovery_start_hook.call(recoverable)
791
+ end
792
+
793
+ def handle_recovery(recoverable)
794
+ @recovery_hook.call(recoverable)
795
+ end
796
+ end
649
797
  end
650
798
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module MarchHare
4
- VERSION = "3.1.1"
4
+ VERSION = "4.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: march_hare
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 4.3.0
5
5
  platform: java
6
6
  authors:
7
7
  - Theo Hultberg
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-03-01 00:00:00.000000000 Z
12
+ date: 2020-09-30 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: RabbitMQ client for JRuby built around the official RabbitMQ Java client
15
15
  email:
@@ -27,6 +27,7 @@ files:
27
27
  - lib/march_hare/consumers.rb
28
28
  - lib/march_hare/consumers/base.rb
29
29
  - lib/march_hare/consumers/blocking.rb
30
+ - lib/march_hare/exception_handler.rb
30
31
  - lib/march_hare/exceptions.rb
31
32
  - lib/march_hare/exchange.rb
32
33
  - lib/march_hare/juc.rb
@@ -55,8 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
56
  - !ruby/object:Gem::Version
56
57
  version: '0'
57
58
  requirements: []
58
- rubyforge_project: march_hare
59
- rubygems_version: 2.6.13
59
+ rubygems_version: 3.0.6
60
60
  signing_key:
61
61
  specification_version: 4
62
62
  summary: RabbitMQ client for JRuby built around the official RabbitMQ Java client