hot_bunnies 2.0.0.pre11-java → 2.0.0.pre12-java
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|