hot_bunnies 2.0.0.pre11-java → 2.0.0.pre12-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.
- data/lib/hot_bunnies.rb +2 -0
- data/lib/hot_bunnies/channel.rb +66 -47
- data/lib/hot_bunnies/consumers/base.rb +2 -0
- data/lib/hot_bunnies/exchange.rb +91 -3
- data/lib/hot_bunnies/metadata.rb +4 -1
- data/lib/hot_bunnies/queue.rb +24 -11
- data/lib/hot_bunnies/session.rb +13 -6
- data/lib/hot_bunnies/version.rb +1 -1
- data/lib/hot_bunnies/versioned_delivery_tag.rb +28 -0
- metadata +3 -2
data/lib/hot_bunnies.rb
CHANGED
data/lib/hot_bunnies/channel.rb
CHANGED
@@ -168,6 +168,9 @@ module HotBunnies
|
|
168
168
|
v
|
169
169
|
end
|
170
170
|
|
171
|
+
# Defines a shutdown event callback. Shutdown events are
|
172
|
+
# broadcasted when a channel is closed, either explicitly
|
173
|
+
# or forcefully, or due to a network/peer failure.
|
171
174
|
def on_shutdown(&block)
|
172
175
|
sh = ShutdownListener.new(self, &block)
|
173
176
|
|
@@ -207,7 +210,6 @@ module HotBunnies
|
|
207
210
|
# Recovers basic.qos setting. Used by the Automatic Network Failure
|
208
211
|
# Recovery feature.
|
209
212
|
#
|
210
|
-
# @api plugin
|
211
213
|
def recover_prefetch_setting
|
212
214
|
basic_qos(@prefetch_count) if @prefetch_count
|
213
215
|
end
|
@@ -215,7 +217,6 @@ module HotBunnies
|
|
215
217
|
# Recovers exchanges. Used by the Automatic Network Failure
|
216
218
|
# Recovery feature.
|
217
219
|
#
|
218
|
-
# @api plugin
|
219
220
|
def recover_exchanges
|
220
221
|
@exchanges.values.each do |x|
|
221
222
|
x.recover_from_network_failure
|
@@ -224,8 +225,6 @@ module HotBunnies
|
|
224
225
|
|
225
226
|
# Recovers queues and bindings. Used by the Automatic Network Failure
|
226
227
|
# Recovery feature.
|
227
|
-
#
|
228
|
-
# @api private
|
229
228
|
def recover_queues
|
230
229
|
@queues.values.each do |q|
|
231
230
|
q.recover_from_network_failure
|
@@ -234,8 +233,6 @@ module HotBunnies
|
|
234
233
|
|
235
234
|
# Recovers consumers. Used by the Automatic Network Failure
|
236
235
|
# Recovery feature.
|
237
|
-
#
|
238
|
-
# @api private
|
239
236
|
def recover_consumers
|
240
237
|
@consumers.values.each do |c|
|
241
238
|
self.unregister_consumer(c)
|
@@ -248,6 +245,8 @@ module HotBunnies
|
|
248
245
|
@recoveries_counter.increment
|
249
246
|
end
|
250
247
|
|
248
|
+
attr_reader :recoveries_counter
|
249
|
+
|
251
250
|
# @group Exchanges
|
252
251
|
|
253
252
|
# Declares a headers exchange or looks it up in the cache of previously
|
@@ -285,7 +284,6 @@ module HotBunnies
|
|
285
284
|
# @return [HotBunnies::Exchange] Exchange instance
|
286
285
|
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
287
286
|
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
288
|
-
# @api public
|
289
287
|
def fanout(name, opts = {})
|
290
288
|
dx = Exchange.new(self, name, opts.merge(:type => "fanout")).tap do |x|
|
291
289
|
x.declare!
|
@@ -307,7 +305,6 @@ module HotBunnies
|
|
307
305
|
# @return [HotBunnies::Exchange] Exchange instance
|
308
306
|
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
309
307
|
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
310
|
-
# @api public
|
311
308
|
def direct(name, opts = {})
|
312
309
|
dx = Exchange.new(self, name, opts.merge(:type => "direct")).tap do |x|
|
313
310
|
x.declare!
|
@@ -329,7 +326,6 @@ module HotBunnies
|
|
329
326
|
# @return [HotBunnies::Exchange] Exchange instance
|
330
327
|
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
331
328
|
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
332
|
-
# @api public
|
333
329
|
def topic(name, opts = {})
|
334
330
|
dx = Exchange.new(self, name, opts.merge(:type => "topic")).tap do |x|
|
335
331
|
x.declare!
|
@@ -351,7 +347,6 @@ module HotBunnies
|
|
351
347
|
# @return [HotBunnies::Exchange] Exchange instance
|
352
348
|
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
353
349
|
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions to AMQP 0.9.1 guide
|
354
|
-
# @api public
|
355
350
|
def headers(name, opts = {})
|
356
351
|
dx = Exchange.new(self, name, opts.merge(:type => "headers")).tap do |x|
|
357
352
|
x.declare!
|
@@ -362,7 +357,6 @@ module HotBunnies
|
|
362
357
|
|
363
358
|
# Provides access to the default exchange
|
364
359
|
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
365
|
-
# @api public
|
366
360
|
def default_exchange
|
367
361
|
@default_exchange ||= self.exchange("", :durable => true, :auto_delete => false, :type => "direct")
|
368
362
|
end
|
@@ -374,15 +368,22 @@ module HotBunnies
|
|
374
368
|
# can survive broker restarts? Typically set to true for long-lived exchanges.
|
375
369
|
# @param [Boolean] auto_delete (false) Should this echange be deleted when it is no longer used?
|
376
370
|
# @param [Boolean] passive (false) If true, exchange will be checked for existence. If it does not
|
377
|
-
# exist, {
|
371
|
+
# exist, {HotBunnies::NotFound} will be raised.
|
378
372
|
#
|
379
373
|
# @return RabbitMQ response
|
380
374
|
# @see http://hotbunnies.info/articles/echanges.html Exchanges and Publishing guide
|
381
|
-
# @api public
|
382
375
|
def exchange_declare(name, type, durable = false, auto_delete = false, arguments = nil)
|
383
376
|
@delegate.exchange_declare(name, type, durable, auto_delete, arguments)
|
384
377
|
end
|
385
378
|
|
379
|
+
def exchange_bind(destination, source, routing_key, arguments = nil)
|
380
|
+
@delegate.exchange_bind(destination, source, routing_key, arguments)
|
381
|
+
end
|
382
|
+
|
383
|
+
def exchange_unbind(destination, source, routing_key, arguments = nil)
|
384
|
+
@delegate.exchange_unbind(destination, source, routing_key, arguments)
|
385
|
+
end
|
386
|
+
|
386
387
|
# @endgroup
|
387
388
|
|
388
389
|
|
@@ -401,7 +402,6 @@ module HotBunnies
|
|
401
402
|
# @return [HotBunnies::Queue] Queue that was declared or looked up in the cache
|
402
403
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
403
404
|
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions guide
|
404
|
-
# @api public
|
405
405
|
def queue(name, options={})
|
406
406
|
dq = Queue.new(self, name, @thread_pool, options).tap do |q|
|
407
407
|
q.declare!
|
@@ -421,11 +421,10 @@ module HotBunnies
|
|
421
421
|
# If true, the queue will be automatically deleted when this
|
422
422
|
# connection is closed
|
423
423
|
# @param [Boolean] passive (false) If true, queue will be checked for existence. If it does not
|
424
|
-
# exist, {
|
424
|
+
# exist, {HotBunnies::NotFound} will be raised.
|
425
425
|
#
|
426
426
|
# @return RabbitMQ response
|
427
427
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
428
|
-
# @api public
|
429
428
|
def queue_declare(name, durable, exclusive, auto_delete, arguments = {})
|
430
429
|
converting_rjc_exceptions_to_ruby do
|
431
430
|
@delegate.queue_declare(name, durable, exclusive, auto_delete, arguments)
|
@@ -438,7 +437,6 @@ module HotBunnies
|
|
438
437
|
# @param [String] name Queue name
|
439
438
|
#
|
440
439
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
441
|
-
# @api public
|
442
440
|
def queue_declare_passive(name)
|
443
441
|
converting_rjc_exceptions_to_ruby do
|
444
442
|
@delegate.queue_declare_passive(name)
|
@@ -454,7 +452,6 @@ module HotBunnies
|
|
454
452
|
#
|
455
453
|
# @return RabbitMQ response
|
456
454
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
457
|
-
# @api public
|
458
455
|
def queue_delete(name, if_empty = false, if_unused = false)
|
459
456
|
converting_rjc_exceptions_to_ruby do
|
460
457
|
@delegate.queue_delete(name, if_empty, if_unused)
|
@@ -472,7 +469,6 @@ module HotBunnies
|
|
472
469
|
# @return RabbitMQ response
|
473
470
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
474
471
|
# @see http://hotbunnies.info/articles/bindings.html Bindings guide
|
475
|
-
# @api public
|
476
472
|
def queue_bind(queue, exchange, routing_key, arguments = nil)
|
477
473
|
converting_rjc_exceptions_to_ruby do
|
478
474
|
@delegate.queue_bind(queue, exchange, routing_key, arguments)
|
@@ -490,7 +486,6 @@ module HotBunnies
|
|
490
486
|
# @return RabbitMQ response
|
491
487
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
492
488
|
# @see http://hotbunnies.info/articles/bindings.html Bindings guide
|
493
|
-
# @api public
|
494
489
|
def queue_unbind(queue, exchange, routing_key, arguments = nil)
|
495
490
|
converting_rjc_exceptions_to_ruby do
|
496
491
|
@delegate.queue_unbind(queue, exchange, routing_key, arguments)
|
@@ -503,7 +498,6 @@ module HotBunnies
|
|
503
498
|
#
|
504
499
|
# @return RabbitMQ response
|
505
500
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
506
|
-
# @api public
|
507
501
|
def queue_purge(name)
|
508
502
|
converting_rjc_exceptions_to_ruby do
|
509
503
|
@delegate.queue_purge(name)
|
@@ -519,7 +513,7 @@ module HotBunnies
|
|
519
513
|
#
|
520
514
|
# @param [String] exchange Exchange to publish to
|
521
515
|
# @param [String] routing_key Routing key
|
522
|
-
# @param [String] body Message payload. It will never be modified by
|
516
|
+
# @param [String] body Message payload. It will never be modified by HotBunnies or RabbitMQ in any way.
|
523
517
|
# @option opts [Boolean] :mandatory Should the message be returned if it cannot be routed to any queue?
|
524
518
|
#
|
525
519
|
# @param [Hash] properties Message properties
|
@@ -538,7 +532,6 @@ module HotBunnies
|
|
538
532
|
# @option properties [String] :app_id Optional application ID
|
539
533
|
#
|
540
534
|
# @return [HotBunnies::Channel] Self
|
541
|
-
# @api public
|
542
535
|
def basic_publish(exchange, routing_key, mandatory, properties, body)
|
543
536
|
converting_rjc_exceptions_to_ruby do
|
544
537
|
@delegate.basic_publish(exchange, routing_key, mandatory, false, BasicPropertiesBuilder.build_properties_from(properties || Hash.new), body)
|
@@ -583,7 +576,6 @@ module HotBunnies
|
|
583
576
|
# @param [Integer] prefetch_count Prefetch (QoS setting) for this channel
|
584
577
|
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
585
578
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
586
|
-
# @api public
|
587
579
|
def prefetch=(n)
|
588
580
|
basic_qos(n)
|
589
581
|
end
|
@@ -594,10 +586,9 @@ module HotBunnies
|
|
594
586
|
# @param [Boolean] multiple (false) Should all unacknowledged messages up to this be acknowledged as well?
|
595
587
|
# @see #nack
|
596
588
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
597
|
-
# @api public
|
598
589
|
def ack(delivery_tag, multiple = false)
|
599
|
-
|
600
|
-
basic_ack(delivery_tag, multiple)
|
590
|
+
guarding_against_stale_delivery_tags(delivery_tag) do
|
591
|
+
basic_ack(delivery_tag.to_i, multiple)
|
601
592
|
end
|
602
593
|
end
|
603
594
|
alias acknowledge ack
|
@@ -610,15 +601,14 @@ module HotBunnies
|
|
610
601
|
# @see #ack
|
611
602
|
# @see #nack
|
612
603
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
613
|
-
# @api public
|
614
604
|
def reject(delivery_tag, requeue = false)
|
615
|
-
|
616
|
-
basic_reject(delivery_tag, requeue)
|
605
|
+
guarding_against_stale_delivery_tags(delivery_tag) do
|
606
|
+
basic_reject(delivery_tag.to_i, requeue)
|
617
607
|
end
|
618
608
|
end
|
619
609
|
|
620
610
|
# Rejects a message. A rejected message can be requeued or
|
621
|
-
# dropped by RabbitMQ. This method is similar to {
|
611
|
+
# dropped by RabbitMQ. This method is similar to {HotBunnies::Channel#reject} but
|
622
612
|
# supports rejecting multiple messages at once, and is usually preferred.
|
623
613
|
#
|
624
614
|
# @param [Integer] delivery_tag Delivery tag to reject
|
@@ -626,10 +616,9 @@ module HotBunnies
|
|
626
616
|
# @param [Boolean] requeue (false) Should this message be requeued instead of dropping it?
|
627
617
|
# @see #ack
|
628
618
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
629
|
-
# @api public
|
630
619
|
def nack(delivery_tag, multiple = false, requeue = false)
|
631
|
-
|
632
|
-
basic_nack(delivery_tag, multiple, requeue)
|
620
|
+
guarding_against_stale_delivery_tags(delivery_tag) do
|
621
|
+
basic_nack(delivery_tag.to_i, multiple, requeue)
|
633
622
|
end
|
634
623
|
end
|
635
624
|
|
@@ -640,7 +629,7 @@ module HotBunnies
|
|
640
629
|
# @return [NilClass] nil
|
641
630
|
#
|
642
631
|
# @example Requeue a message
|
643
|
-
# conn =
|
632
|
+
# conn = HotBunnies.new
|
644
633
|
# conn.start
|
645
634
|
#
|
646
635
|
# ch = conn.create_channel
|
@@ -650,7 +639,7 @@ module HotBunnies
|
|
650
639
|
# end
|
651
640
|
#
|
652
641
|
# @example Reject a message
|
653
|
-
# conn =
|
642
|
+
# conn = HotBunnies.new
|
654
643
|
# conn.start
|
655
644
|
#
|
656
645
|
# ch = conn.create_channel
|
@@ -660,7 +649,7 @@ module HotBunnies
|
|
660
649
|
# end
|
661
650
|
#
|
662
651
|
# @example Requeue a message fetched via basic.get
|
663
|
-
# conn =
|
652
|
+
# conn = HotBunnies.new
|
664
653
|
# conn.start
|
665
654
|
#
|
666
655
|
# ch = conn.create_channel
|
@@ -670,20 +659,26 @@ module HotBunnies
|
|
670
659
|
#
|
671
660
|
# @see #basic_nack
|
672
661
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
673
|
-
# @api public
|
674
662
|
def basic_reject(delivery_tag, requeue)
|
675
663
|
converting_rjc_exceptions_to_ruby do
|
676
|
-
@delegate.basic_reject(delivery_tag, requeue)
|
664
|
+
@delegate.basic_reject(delivery_tag.to_i, requeue)
|
677
665
|
end
|
678
666
|
end
|
679
667
|
|
668
|
+
# Acknowledges one or more messages (deliveries).
|
669
|
+
#
|
670
|
+
# @param [Integer] delivery_tag Delivery tag obtained from delivery info
|
671
|
+
# @param [Boolean] multiple Should all deliveries up to this one be acknowledged?
|
672
|
+
# @return [NilClass] nil
|
673
|
+
#
|
674
|
+
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
680
675
|
def basic_ack(delivery_tag, multiple)
|
681
676
|
converting_rjc_exceptions_to_ruby do
|
682
|
-
@delegate.basic_ack(delivery_tag, multiple)
|
677
|
+
@delegate.basic_ack(delivery_tag.to_i, multiple)
|
683
678
|
end
|
684
679
|
end
|
685
680
|
|
686
|
-
# Rejects or requeues messages just like {
|
681
|
+
# Rejects or requeues messages just like {HotBunnies::Channel#basic_reject} but can do so
|
687
682
|
# with multiple messages at once.
|
688
683
|
#
|
689
684
|
# @param [Integer] delivery_tag Delivery tag obtained from delivery info
|
@@ -693,10 +688,9 @@ module HotBunnies
|
|
693
688
|
#
|
694
689
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
695
690
|
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions guide
|
696
|
-
# @api public
|
697
691
|
def basic_nack(delivery_tag, multiple = false, requeue = false)
|
698
692
|
converting_rjc_exceptions_to_ruby do
|
699
|
-
@delegate.basic_nack(delivery_tag, multiple, requeue)
|
693
|
+
@delegate.basic_nack(delivery_tag.to_i, multiple, requeue)
|
700
694
|
end
|
701
695
|
end
|
702
696
|
|
@@ -704,7 +698,6 @@ module HotBunnies
|
|
704
698
|
#
|
705
699
|
# @param [Boolean] requeue Should messages be requeued?
|
706
700
|
# @return RabbitMQ response
|
707
|
-
# @api public
|
708
701
|
def basic_recover(requeue = true)
|
709
702
|
converting_rjc_exceptions_to_ruby do
|
710
703
|
@delegate.basic_recover(requeue)
|
@@ -715,7 +708,6 @@ module HotBunnies
|
|
715
708
|
#
|
716
709
|
# @param [Boolean] requeue Should messages be requeued?
|
717
710
|
# @return RabbitMQ response
|
718
|
-
# @api public
|
719
711
|
def basic_recover_async(requeue = true)
|
720
712
|
converting_rjc_exceptions_to_ruby do
|
721
713
|
@delegate.basic_recover_async(requeue)
|
@@ -724,7 +716,11 @@ module HotBunnies
|
|
724
716
|
|
725
717
|
# @endgroup
|
726
718
|
|
727
|
-
|
719
|
+
# Enables publisher confirms on the channel.
|
720
|
+
# @return [NilClass] nil
|
721
|
+
#
|
722
|
+
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishers guide
|
723
|
+
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions guide
|
728
724
|
def confirm_select
|
729
725
|
converting_rjc_exceptions_to_ruby do
|
730
726
|
@delegate.confirm_select
|
@@ -753,31 +749,37 @@ module HotBunnies
|
|
753
749
|
@delegate.next_publisher_seq_no
|
754
750
|
end
|
755
751
|
|
752
|
+
# Enables transactions on the channel
|
756
753
|
def tx_select
|
757
754
|
converting_rjc_exceptions_to_ruby do
|
758
755
|
@delegate.tx_select
|
759
756
|
end
|
760
757
|
end
|
761
758
|
|
759
|
+
# Commits a transaction
|
762
760
|
def tx_commit
|
763
761
|
converting_rjc_exceptions_to_ruby do
|
764
762
|
@delegate.tx_commit
|
765
763
|
end
|
766
764
|
end
|
767
765
|
|
766
|
+
# Rolls back a transaction
|
768
767
|
def tx_rollback
|
769
768
|
converting_rjc_exceptions_to_ruby do
|
770
769
|
@delegate.tx_rollback
|
771
770
|
end
|
772
771
|
end
|
773
772
|
|
773
|
+
# Enables or disables channel flow. This feature id deprecated
|
774
|
+
# in RabbitMQ.
|
774
775
|
def channel_flow(active)
|
775
776
|
converting_rjc_exceptions_to_ruby do
|
776
777
|
@delegate.channel_flow(active)
|
777
778
|
end
|
778
779
|
end
|
779
780
|
|
780
|
-
|
781
|
+
# Defines a returned message handler.
|
782
|
+
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishers guide
|
781
783
|
def on_return(&block)
|
782
784
|
self.add_return_listener(BlockReturnListener.from(block))
|
783
785
|
end
|
@@ -791,6 +793,7 @@ module HotBunnies
|
|
791
793
|
# Implementation
|
792
794
|
#
|
793
795
|
|
796
|
+
# @private
|
794
797
|
class BlockReturnListener
|
795
798
|
include com.rabbitmq.client.ReturnListener
|
796
799
|
|
@@ -866,5 +869,21 @@ module HotBunnies
|
|
866
869
|
Exceptions.convert_and_reraise(e)
|
867
870
|
end
|
868
871
|
end
|
872
|
+
|
873
|
+
# @private
|
874
|
+
def guarding_against_stale_delivery_tags(tag, &block)
|
875
|
+
case tag
|
876
|
+
# if a fixnum was passed, execute unconditionally. MK.
|
877
|
+
when Fixnum then
|
878
|
+
block.call
|
879
|
+
# versioned delivery tags should be checked to avoid
|
880
|
+
# sending out stale (invalid) tags after channel was reopened
|
881
|
+
# during network failure recovery. MK.
|
882
|
+
when VersionedDeliveryTag then
|
883
|
+
if !tag.stale?(@recoveries_counter.get)
|
884
|
+
block.call
|
885
|
+
end
|
886
|
+
end
|
887
|
+
end
|
869
888
|
end
|
870
889
|
end
|
data/lib/hot_bunnies/exchange.rb
CHANGED
@@ -3,8 +3,19 @@
|
|
3
3
|
module HotBunnies
|
4
4
|
import com.rabbitmq.client.AMQP
|
5
5
|
|
6
|
+
# Represents AMQP 0.9.1 exchanges.
|
7
|
+
#
|
8
|
+
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
9
|
+
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions guide
|
6
10
|
class Exchange
|
7
|
-
|
11
|
+
# @return [String] Exchange name
|
12
|
+
attr_reader :name
|
13
|
+
# @return [HotBunnies::Channel] Channel this exchange object uses
|
14
|
+
attr_reader :channel
|
15
|
+
|
16
|
+
# Type of this exchange (one of: :direct, :fanout, :topic, :headers).
|
17
|
+
# @return [Symbol]
|
18
|
+
attr_reader :type
|
8
19
|
|
9
20
|
def initialize(channel, name, options = {})
|
10
21
|
raise ArgumentError, "exchange channel cannot be nil" if channel.nil?
|
@@ -17,6 +28,29 @@ module HotBunnies
|
|
17
28
|
@options = {:type => :fanout, :durable => false, :auto_delete => false, :internal => false, :passive => false}.merge(options)
|
18
29
|
end
|
19
30
|
|
31
|
+
# Publishes a message
|
32
|
+
#
|
33
|
+
# @param [String] payload Message payload. It will never be modified by HotBunnies or RabbitMQ in any way.
|
34
|
+
# @param [Hash] opts Message properties (metadata) and delivery settings
|
35
|
+
#
|
36
|
+
# @option opts [String] :routing_key Routing key
|
37
|
+
# @option opts [Boolean] :persistent Should the message be persisted to disk?
|
38
|
+
# @option opts [Boolean] :mandatory Should the message be returned if it cannot be routed to any queue?
|
39
|
+
# @option opts [Integer] :timestamp A timestamp associated with this message
|
40
|
+
# @option opts [Integer] :expiration Expiration time after which the message will be deleted
|
41
|
+
# @option opts [String] :type Message type, e.g. what type of event or command this message represents. Can be any string
|
42
|
+
# @option opts [String] :reply_to Queue name other apps should send the response to
|
43
|
+
# @option opts [String] :content_type Message content type (e.g. application/json)
|
44
|
+
# @option opts [String] :content_encoding Message content encoding (e.g. gzip)
|
45
|
+
# @option opts [String] :correlation_id Message correlated to this one, e.g. what request this message is a reply for
|
46
|
+
# @option opts [Integer] :priority Message priority, 0 to 9. Not used by RabbitMQ, only applications
|
47
|
+
# @option opts [String] :message_id Any message identifier
|
48
|
+
# @option opts [String] :user_id Optional user ID. Verified by RabbitMQ against the actual connection username
|
49
|
+
# @option opts [String] :app_id Optional application ID
|
50
|
+
#
|
51
|
+
# @return [HotBunnies::Exchange] Self
|
52
|
+
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
53
|
+
# @api public
|
20
54
|
def publish(body, opts = {})
|
21
55
|
options = {:routing_key => '', :mandatory => false}.merge(opts)
|
22
56
|
@channel.basic_publish(@name,
|
@@ -26,24 +60,78 @@ module HotBunnies
|
|
26
60
|
body.to_java_bytes)
|
27
61
|
end
|
28
62
|
|
63
|
+
# Deletes the exchange unless it is predefined
|
64
|
+
#
|
65
|
+
# @param [Hash] options Options
|
66
|
+
#
|
67
|
+
# @option opts [Boolean] if_unused (false) Should this exchange be deleted only if it is no longer used
|
68
|
+
#
|
69
|
+
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
70
|
+
# @api public
|
29
71
|
def delete(options={})
|
30
|
-
@channel.
|
72
|
+
@channel.deregister_exchange(self)
|
73
|
+
@channel.exchange_delete(@name, options.fetch(:if_unused, false)) unless predefined?
|
31
74
|
end
|
32
75
|
|
76
|
+
# Binds an exchange to another (source) exchange using exchange.bind AMQP 0.9.1 extension
|
77
|
+
# that RabbitMQ provides.
|
78
|
+
#
|
79
|
+
# @param [String] exchange Source exchange name
|
80
|
+
# @param [Hash] options Options
|
81
|
+
#
|
82
|
+
# @option opts [String] routing_key (nil) Routing key used for binding
|
83
|
+
# @option opts [Hash] arguments ({}) Optional arguments
|
84
|
+
#
|
85
|
+
# @return [HotBunnies::Exchange] Self
|
86
|
+
# @see http://hotbunnies.info/articles/exchanges.html Exchanges and Publishing guide
|
87
|
+
# @see http://hotbunnies.info/articles/bindings.html Bindings guide
|
88
|
+
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions guide
|
89
|
+
# @api public
|
33
90
|
def bind(exchange, options={})
|
34
91
|
exchange_name = if exchange.respond_to?(:name) then exchange.name else exchange.to_s end
|
35
92
|
@channel.exchange_bind(@name, exchange_name, options.fetch(:routing_key, ''))
|
36
93
|
end
|
37
94
|
|
95
|
+
# Unbinds an exchange from another (source) exchange using exchange.unbind AMQP 0.9.1 extension
|
96
|
+
# that RabbitMQ provides.
|
97
|
+
#
|
98
|
+
# @param [String] source Source exchange name
|
99
|
+
# @param [Hash] opts Options
|
100
|
+
#
|
101
|
+
# @option opts [String] routing_key (nil) Routing key used for binding
|
102
|
+
# @option opts [Hash] arguments ({}) Optional arguments
|
103
|
+
#
|
104
|
+
# @return [Bunny::Exchange] Self
|
105
|
+
# @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
|
106
|
+
# @see http://rubybunny.info/articles/bindings.html Bindings guide
|
107
|
+
# @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
|
108
|
+
# @api public
|
109
|
+
def unbind(exchange, opts = {})
|
110
|
+
exchange_name = if exchange.respond_to?(:name) then exchange.name else exchange.to_s end
|
111
|
+
@channel.exchange_unbind(@name, exchange_name, opts.fetch(:routing_key, ''), opts[:arguments])
|
112
|
+
end
|
113
|
+
|
114
|
+
# @return [Boolean] true if this exchange is a pre-defined one (amq.direct, amq.fanout, amq.match and so on)
|
38
115
|
def predefined?
|
39
116
|
@name.empty? || @name.start_with?("amq.")
|
40
117
|
end
|
41
118
|
|
119
|
+
# Waits until all outstanding publisher confirms on the channel
|
120
|
+
# arrive.
|
121
|
+
#
|
122
|
+
# This is a convenience method that delegates to {Channel#wait_for_confirms}
|
123
|
+
#
|
124
|
+
# @api public
|
125
|
+
def wait_for_confirms
|
126
|
+
@channel.wait_for_confirms
|
127
|
+
end
|
128
|
+
|
129
|
+
|
42
130
|
#
|
43
131
|
# Implementation
|
44
132
|
#
|
45
133
|
|
46
|
-
# @
|
134
|
+
# @private
|
47
135
|
def declare!
|
48
136
|
unless predefined?
|
49
137
|
if @options[:passive]
|
data/lib/hot_bunnies/metadata.rb
CHANGED
@@ -19,7 +19,6 @@ module HotBunnies
|
|
19
19
|
|
20
20
|
begin :envelope_delegation
|
21
21
|
[
|
22
|
-
:delivery_tag,
|
23
22
|
:routing_key,
|
24
23
|
:redeliver,
|
25
24
|
:exchange
|
@@ -30,6 +29,10 @@ module HotBunnies
|
|
30
29
|
alias_method :redelivered?, :redeliver
|
31
30
|
end
|
32
31
|
|
32
|
+
def delivery_tag
|
33
|
+
@delivery_tag ||= VersionedDeliveryTag.new(@envelope.delivery_tag, @channel.recoveries_counter.get)
|
34
|
+
end
|
35
|
+
|
33
36
|
begin :message_properties_delegation
|
34
37
|
[
|
35
38
|
:content_encoding,
|
data/lib/hot_bunnies/queue.rb
CHANGED
@@ -28,7 +28,6 @@ module HotBunnies
|
|
28
28
|
# @see HotBunnies::Channel#queue
|
29
29
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
30
30
|
# @see http://hotbunnies.info/articles/extensions.html RabbitMQ Extensions guide
|
31
|
-
# @api public
|
32
31
|
def initialize(channel, name, thread_pool, options={})
|
33
32
|
@channel = channel
|
34
33
|
@name = name
|
@@ -46,35 +45,30 @@ module HotBunnies
|
|
46
45
|
|
47
46
|
|
48
47
|
# @return [Boolean] true if this queue was declared as durable (will survive broker restart).
|
49
|
-
# @api public
|
50
48
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
51
49
|
def durable?
|
52
50
|
@durable
|
53
51
|
end # durable?
|
54
52
|
|
55
53
|
# @return [Boolean] true if this queue was declared as exclusive (limited to just one consumer)
|
56
|
-
# @api public
|
57
54
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
58
55
|
def exclusive?
|
59
56
|
@exclusive
|
60
57
|
end # exclusive?
|
61
58
|
|
62
59
|
# @return [Boolean] true if this queue was declared as automatically deleted (deleted as soon as last consumer unbinds).
|
63
|
-
# @api public
|
64
60
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
65
61
|
def auto_delete?
|
66
62
|
@auto_delete
|
67
63
|
end # auto_delete?
|
68
64
|
|
69
65
|
# @return [Boolean] true if this queue was declared as server named.
|
70
|
-
# @api public
|
71
66
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
72
67
|
def server_named?
|
73
68
|
@server_named
|
74
69
|
end # server_named?
|
75
70
|
|
76
71
|
# @return [Hash] Additional optional arguments (typically used by RabbitMQ extensions and plugins)
|
77
|
-
# @api public
|
78
72
|
def arguments
|
79
73
|
@arguments
|
80
74
|
end
|
@@ -91,7 +85,6 @@ module HotBunnies
|
|
91
85
|
#
|
92
86
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
93
87
|
# @see http://hotbunnies.info/articles/bindings.html Bindings guide
|
94
|
-
# @api public
|
95
88
|
def bind(exchange, options={})
|
96
89
|
exchange_name = if exchange.respond_to?(:name) then
|
97
90
|
exchange.name
|
@@ -118,7 +111,6 @@ module HotBunnies
|
|
118
111
|
#
|
119
112
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
120
113
|
# @see http://hotbunnies.info/articles/bindings.html Bindings guide
|
121
|
-
# @api public
|
122
114
|
def unbind(exchange, options={})
|
123
115
|
exchange_name = if exchange.respond_to?(:name) then
|
124
116
|
exchange.name
|
@@ -139,11 +131,13 @@ module HotBunnies
|
|
139
131
|
# @option [Boolean] if_empty (false) Should this queue be deleted only if it has no messages?
|
140
132
|
#
|
141
133
|
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
142
|
-
# @api public
|
143
134
|
def delete(if_unused = false, if_empty = false)
|
144
135
|
@channel.queue_delete(@name, if_unused, if_empty)
|
145
136
|
end
|
146
137
|
|
138
|
+
# Purges a queue (removes all messages from it)
|
139
|
+
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
140
|
+
# @api public
|
147
141
|
def purge
|
148
142
|
@channel.queue_purge(@name)
|
149
143
|
end
|
@@ -167,8 +161,21 @@ module HotBunnies
|
|
167
161
|
end
|
168
162
|
end
|
169
163
|
|
164
|
+
# Adds a consumer to the queue (subscribes for message deliveries).
|
165
|
+
#
|
166
|
+
# @param [Hash] opts Options
|
167
|
+
#
|
168
|
+
# @option opts [Boolean] :manual_ack (false) Will this consumer use manual acknowledgements?
|
169
|
+
# @option opts [Boolean] :exclusive (false) Should this consumer be exclusive for this queue?
|
170
|
+
# @option opts [Boolean] :block (false) Should the call block calling thread?
|
171
|
+
# @option opts [#call] :on_cancellation Block to execute when this consumer is cancelled remotely (e.g. via the RabbitMQ Management plugin)
|
172
|
+
# @option opts [String] :consumer_tag Unique consumer identifier. It is usually recommended to let HotBunnies generate it for you.
|
173
|
+
# @option opts [Hash] :arguments ({}) Additional (optional) arguments, typically used by RabbitMQ extensions
|
174
|
+
#
|
175
|
+
# @see http://hotbunnies.info/articles/queues.html Queues and Consumers guide
|
176
|
+
# @api public
|
170
177
|
def subscribe(opts = {}, &block)
|
171
|
-
subscribe_with(build_consumer(opts, &block))
|
178
|
+
subscribe_with(build_consumer(opts, &block), opts)
|
172
179
|
end
|
173
180
|
|
174
181
|
def subscribe_with(consumer, opts = {})
|
@@ -182,23 +189,28 @@ module HotBunnies
|
|
182
189
|
consumer
|
183
190
|
end
|
184
191
|
|
192
|
+
# @return [Array<Integer>] A pair with information about the number of queue messages and consumers
|
193
|
+
# @see #message_count
|
194
|
+
# @see #consumer_count
|
185
195
|
def status
|
186
196
|
response = @channel.queue_declare_passive(@name)
|
187
197
|
[response.message_count, response.consumer_count]
|
188
198
|
end
|
189
199
|
|
200
|
+
# @return [Integer] How many messages the queue has ready (e.g. not delivered but not unacknowledged)
|
190
201
|
def message_count
|
191
202
|
response = @channel.queue_declare_passive(@name)
|
192
203
|
response.message_count
|
193
204
|
end
|
194
205
|
|
206
|
+
# @return [Integer] How many active consumers the queue has
|
195
207
|
def consumer_count
|
196
208
|
response = @channel.queue_declare_passive(@name)
|
197
209
|
response.consumer_count
|
198
210
|
end
|
199
211
|
|
200
212
|
# Publishes a message to the queue via default exchange. Takes the same arguments
|
201
|
-
# as {
|
213
|
+
# as {HotBunnies::Exchange#publish}
|
202
214
|
#
|
203
215
|
# @see HotBunnies::Exchange#publish
|
204
216
|
# @see HotBunnies::Channel#default_exchange
|
@@ -213,6 +225,7 @@ module HotBunnies
|
|
213
225
|
# Implementation
|
214
226
|
#
|
215
227
|
|
228
|
+
# @private
|
216
229
|
def declare!
|
217
230
|
response = if @options[:passive]
|
218
231
|
then @channel.queue_declare_passive(@name)
|
data/lib/hot_bunnies/session.rb
CHANGED
@@ -13,7 +13,6 @@ module HotBunnies
|
|
13
13
|
# @see .connect
|
14
14
|
# @see #create_channel
|
15
15
|
# @see #close
|
16
|
-
# @api public
|
17
16
|
# @see http://hotbunnies.info/articles/getting_started.html Getting Started guide
|
18
17
|
# @see http://hotbunnies.info/articles/connecting.html Connecting to RabbitMQ guide
|
19
18
|
class Session
|
@@ -38,9 +37,6 @@ module HotBunnies
|
|
38
37
|
# @option options [Boolean] :tls (false) Set to true to use TLS/SSL connection. This will switch port to 5671 by default.
|
39
38
|
#
|
40
39
|
# @see http://hotbunnies.info/articles/connecting.html Connecting to RabbitMQ guide
|
41
|
-
#
|
42
|
-
#
|
43
|
-
# @api public
|
44
40
|
def self.connect(options={})
|
45
41
|
cf = ConnectionFactory.new
|
46
42
|
|
@@ -107,7 +103,6 @@ module HotBunnies
|
|
107
103
|
# @return [HotBunnies::Channel] Newly created channel
|
108
104
|
# @see HotBunnies::Channel
|
109
105
|
# @see http://hotbunnies.info/articles/getting_started.html Getting Started guide
|
110
|
-
# @api public
|
111
106
|
def create_channel(n = nil)
|
112
107
|
jc = if n
|
113
108
|
@connection.create_channel(n)
|
@@ -121,6 +116,11 @@ module HotBunnies
|
|
121
116
|
ch
|
122
117
|
end
|
123
118
|
|
119
|
+
# Closes connection gracefully.
|
120
|
+
#
|
121
|
+
# This includes shutting down consumer work pool gracefully,
|
122
|
+
# waiting up to 5 seconds for all consumer deliveries to be
|
123
|
+
# processed.
|
124
124
|
def close
|
125
125
|
@channels.select { |_, ch| ch.open? }.each do |_, ch|
|
126
126
|
ch.close
|
@@ -134,11 +134,15 @@ module HotBunnies
|
|
134
134
|
@connection.close
|
135
135
|
end
|
136
136
|
|
137
|
+
# @return [Boolean] true if connection is open, false otherwise
|
137
138
|
def open?
|
138
139
|
@connection.open?
|
139
140
|
end
|
140
141
|
alias connected? open?
|
141
142
|
|
143
|
+
# Defines a shutdown event callback. Shutdown events are
|
144
|
+
# broadcasted when a connection is closed, either explicitly
|
145
|
+
# or forcefully, or due to a network/peer failure.
|
142
146
|
def on_shutdown(&block)
|
143
147
|
sh = ShutdownListener.new(self, &block)
|
144
148
|
@shutdown_hooks << sh
|
@@ -164,6 +168,8 @@ module HotBunnies
|
|
164
168
|
@connetion.remove_shutdown_listener(@automatic_recovery_hook) if @automatic_recovery_hook
|
165
169
|
end
|
166
170
|
|
171
|
+
# Begins automatic connection recovery (typically only used internally
|
172
|
+
# to recover from network failures)
|
167
173
|
def automatically_recover
|
168
174
|
# recovering immediately makes little sense. Wait a bit first. MK.
|
169
175
|
java.lang.Thread.sleep(@network_recovery_interval * 1000)
|
@@ -191,6 +197,7 @@ module HotBunnies
|
|
191
197
|
@connection.flush
|
192
198
|
end
|
193
199
|
|
200
|
+
# @private
|
194
201
|
def heartbeat=(n)
|
195
202
|
@connection.heartbeat = n
|
196
203
|
end
|
@@ -212,7 +219,6 @@ module HotBunnies
|
|
212
219
|
end
|
213
220
|
|
214
221
|
# @return [String]
|
215
|
-
# @api public
|
216
222
|
def to_s
|
217
223
|
"#<#{self.class.name}:#{object_id} #{@cf.username}@#{@cf.host}:#{@cf.port}, vhost=#{@cf.virtual_host}>"
|
218
224
|
end
|
@@ -222,6 +228,7 @@ module HotBunnies
|
|
222
228
|
# Implementation
|
223
229
|
#
|
224
230
|
|
231
|
+
# @private
|
225
232
|
def register_channel(ch)
|
226
233
|
@channels[ch.channel_number] = ch
|
227
234
|
end
|
data/lib/hot_bunnies/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
module HotBunnies
|
2
|
+
# Wraps a delivery tag (which is an integer) so that {Bunny::Channel} could
|
3
|
+
# detect stale tags after connection recovery.
|
4
|
+
#
|
5
|
+
# @private
|
6
|
+
class VersionedDeliveryTag
|
7
|
+
attr_reader :tag
|
8
|
+
attr_reader :version
|
9
|
+
|
10
|
+
def initialize(tag, version)
|
11
|
+
raise ArgumentError.new("tag cannot be nil") unless tag
|
12
|
+
raise ArgumentError.new("version cannot be nil") unless version
|
13
|
+
|
14
|
+
@tag = tag
|
15
|
+
@version = version
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_i
|
19
|
+
@tag
|
20
|
+
end
|
21
|
+
|
22
|
+
def stale?(version)
|
23
|
+
raise ArgumentError.new("version cannot be nil") unless version
|
24
|
+
|
25
|
+
@version < version
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hot_bunnies
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.pre12
|
5
5
|
prerelease: 6
|
6
6
|
platform: java
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-08-
|
13
|
+
date: 2013-08-27 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: RabbitMQ client for JRuby built around the official RabbitMQ Java client
|
16
16
|
email:
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- lib/hot_bunnies/shutdown_listener.rb
|
36
36
|
- lib/hot_bunnies/thread_pools.rb
|
37
37
|
- lib/hot_bunnies/version.rb
|
38
|
+
- lib/hot_bunnies/versioned_delivery_tag.rb
|
38
39
|
homepage: http://hotbunnies.info
|
39
40
|
licenses: []
|
40
41
|
post_install_message:
|