action_subscriber 5.1.4.pre0 → 5.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be413ce9308a022df33f96d787b50b059bd6700911e1a090f98f454777d14a1f
4
- data.tar.gz: c09a951d4f0343dc9cb2e23484333656fae3111b5e558668436d3fbdf63d0379
3
+ metadata.gz: 341fae9698b9a950fe6dcbc2263fcfba9f8f2b87de7156753714a2f5459dc6d0
4
+ data.tar.gz: 4ee41e85aab759a85339aaa174b499d34ba3967b90220ddfee3e43ada8191282
5
5
  SHA512:
6
- metadata.gz: c303e23007ddc09b9bb05d09f269d637ce0e7ac8b7ec0c7325412d9afd84fb81f94590e3230716101c82be2799ae9223745ea8e79595e3bd669e932127588351
7
- data.tar.gz: 4920a7deec1c46b47c9de7bd467b16ef8e5995050da4c1244c113115bde344fd1b27781e925d72fa1dfa391f2a6adf40ca22c7cd608f5e47ba8cac834c8caa8f
6
+ metadata.gz: b21075dc61f36ba0b20923178524030f95d4a62be67275ae5fb16db18175e63e27224640f96a9a11e5e624c0a145d37b092d6b627e1f7fa779c07c6b0ea9229d
7
+ data.tar.gz: ea278d62aee15c5bb1d01832c104e33ff1f305aecf373e547a8ff11929b2771167c51e5a4d029e915065113ffc8bfb1a7d445506abb94e0d0026c8dcd045335d
@@ -1,9 +1,13 @@
1
1
  language: ruby
2
+ os:
3
+ linux
4
+ dist:
5
+ trusty
2
6
  rvm:
3
- - 2.2.6
4
- - 2.3.3
5
- - jruby-9.0.5.0
6
- - jruby-9.1.7.0
7
+ - 2.3.8
8
+ - 2.5.7
9
+ - jruby-9.1.12.0
10
+ - jruby-9.2.7.0
7
11
  - jruby-head
8
12
  services:
9
13
  - rabbitmq
data/README.md CHANGED
@@ -135,6 +135,7 @@ Other configuration options include :
135
135
  * config.network_recovery_interval - reconnection interval for TCP connection failures (default 1)
136
136
  * config.password - RabbitMQ password (default "guest")
137
137
  * config.prefetch - number of messages to hold in the local queue in subscriber mode
138
+ * config.resubscribe_on_consumer_cancellation - resubscribe when the consumer is cancelled (queue deleted or cluster fails, default true)
138
139
  * config.seconds_to_wait_for_graceful_shutdown - time to wait before force stopping server after shutdown signal
139
140
  * config.threadpool_size - set the number of threads available to action_subscriber
140
141
  * config.timeout - how many seconds to allow rabbit to respond before timing out
@@ -26,35 +26,52 @@ module ActionSubscriber
26
26
 
27
27
  def start_subscribers!
28
28
  subscriptions.each do |subscription|
29
- route = subscription[:route]
30
- queue = subscription[:queue]
31
- channel = queue.channel
32
- threadpool = ::ActionSubscriber::ThreadPools.threadpools.fetch(route.threadpool_name)
33
- channel.prefetch(route.prefetch) if route.acknowledgements?
34
- consumer = ::Bunny::Consumer.new(channel, queue, channel.generate_consumer_tag, !route.acknowledgements?)
35
- consumer.on_delivery do |delivery_info, properties, encoded_payload|
36
- ::ActiveSupport::Notifications.instrument "received_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
37
- properties = {
38
- :action => route.action,
39
- :channel => queue.channel,
40
- :content_type => properties.content_type,
41
- :delivery_tag => delivery_info.delivery_tag,
42
- :exchange => delivery_info.exchange,
43
- :headers => properties.headers,
44
- :message_id => properties.message_id,
45
- :routing_key => delivery_info.routing_key,
46
- :queue => queue.name,
47
- :uses_acknowledgements => route.acknowledgements?,
48
- }
49
- env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
50
- run_env(env, threadpool)
51
- end
52
- bunny_consumers << consumer
53
- queue.subscribe_with(consumer)
29
+ start_subscriber_for_subscription(subscription)
54
30
  end
55
31
  end
56
32
 
57
- private
33
+ private
34
+
35
+ def start_subscriber_for_subscription(subscription)
36
+ route = subscription[:route]
37
+ queue = subscription[:queue]
38
+ channel = queue.channel
39
+ threadpool = ::ActionSubscriber::ThreadPools.threadpools.fetch(route.threadpool_name)
40
+ channel.prefetch(route.prefetch) if route.acknowledgements?
41
+ consumer = ::Bunny::Consumer.new(channel, queue, channel.generate_consumer_tag, !route.acknowledgements?)
42
+
43
+ if ::ActionSubscriber.configuration.resubscribe_on_consumer_cancellation
44
+ # Add cancellation callback to rebuild subscriber on cancel.
45
+ consumer.on_cancellation do
46
+ ::ActionSubscriber.logger.warn "Cancelation received for queue consumer: #{queue.name}, rebuilding subscription..."
47
+ bunny_consumers.delete(consumer)
48
+ channel.close
49
+ queue = subscription[:queue] = setup_queue(route)
50
+ start_subscriber_for_subscription(subscription)
51
+ end
52
+ end
53
+
54
+ consumer.on_delivery do |delivery_info, properties, encoded_payload|
55
+ ::ActiveSupport::Notifications.instrument "received_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
56
+ properties = {
57
+ :action => route.action,
58
+ :channel => queue.channel,
59
+ :content_type => properties.content_type,
60
+ :delivery_tag => delivery_info.delivery_tag,
61
+ :exchange => delivery_info.exchange,
62
+ :headers => properties.headers,
63
+ :message_id => properties.message_id,
64
+ :routing_key => delivery_info.routing_key,
65
+ :queue => queue.name,
66
+ :uses_acknowledgements => route.acknowledgements?,
67
+ }
68
+ env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
69
+ run_env(env, threadpool)
70
+ end
71
+
72
+ bunny_consumers << consumer
73
+ queue.subscribe_with(consumer)
74
+ end
58
75
 
59
76
  def setup_queue(route)
60
77
  channel = ::ActionSubscriber::RabbitConnection.with_connection{|connection| connection.create_channel(nil, 1) }
@@ -16,6 +16,7 @@ module ActionSubscriber
16
16
  :password,
17
17
  :port,
18
18
  :prefetch,
19
+ :resubscribe_on_consumer_cancellation,
19
20
  :seconds_to_wait_for_graceful_shutdown,
20
21
  :threadpool_size,
21
22
  :timeout,
@@ -42,6 +43,7 @@ module ActionSubscriber
42
43
  :password => "guest",
43
44
  :port => 5672,
44
45
  :prefetch => 2,
46
+ :resubscribe_on_consumer_cancellation => true,
45
47
  :seconds_to_wait_for_graceful_shutdown => 30,
46
48
  :threadpool_size => 8,
47
49
  :timeout => 1,
@@ -75,8 +77,8 @@ module ActionSubscriber
75
77
  end
76
78
 
77
79
  ::ActionSubscriber::Configuration::DEFAULTS.each_pair do |key, value|
78
- setting = cli_options[key] || yaml_config[key.to_s]
79
- ::ActionSubscriber.config.__send__("#{key}=", setting) if setting
80
+ exists, setting = fetch_config_value(key, cli_options, yaml_config)
81
+ ::ActionSubscriber.config.__send__("#{key}=", setting) if exists
80
82
  end
81
83
 
82
84
  true
@@ -84,6 +86,15 @@ module ActionSubscriber
84
86
  end
85
87
  end
86
88
 
89
+ def self.fetch_config_value(key, cli_options, yaml_config)
90
+ return [true, cli_options[key]] if cli_options.key?(key)
91
+ return [true, cli_options[key.to_s]] if cli_options.key?(key.to_s)
92
+ return [true, yaml_config[key]] if yaml_config.key?(key)
93
+ return [true, yaml_config[key.to_s]] if yaml_config.key?(key.to_s)
94
+ [false, nil]
95
+ end
96
+ private_class_method :fetch_config_value
97
+
87
98
  ##
88
99
  # Instance Methods
89
100
  #
@@ -1,5 +1,38 @@
1
1
  module ActionSubscriber
2
2
  module DSL
3
+ class Filter
4
+ attr_accessor :callback_method
5
+ attr_accessor :included_actions
6
+ attr_accessor :excluded_actions
7
+
8
+ def initialize(callback_method, options)
9
+ @callback_method = callback_method
10
+ @included_actions = @excluded_actions = []
11
+ parse_options(options)
12
+ end
13
+
14
+ def matches(action)
15
+ unless included_actions.empty?
16
+ return included_actions.include?(action)
17
+ end
18
+
19
+ unless excluded_actions.empty?
20
+ return false if excluded_actions.include?(action)
21
+ end
22
+
23
+ true
24
+ end
25
+
26
+ private
27
+
28
+ def parse_options(options)
29
+ return unless options
30
+
31
+ @included_actions = options.fetch(:if, [])
32
+ @excluded_actions = options.fetch(:unless, [])
33
+ end
34
+ end
35
+
3
36
  def at_least_once!
4
37
  @_acknowledge_messages = true
5
38
  @_at_least_once = true
@@ -22,11 +55,16 @@ module ActionSubscriber
22
55
  !!@_acknowledge_messages
23
56
  end
24
57
 
25
- def around_filter(filter_method)
26
- around_filters << filter_method unless around_filters.include?(filter_method)
58
+ def around_filter(callback_method, options = nil)
59
+ filter = Filter.new(callback_method, options)
60
+ conditionally_add_filter!(filter)
27
61
  around_filters
28
62
  end
29
63
 
64
+ def conditionally_add_filter!(filter)
65
+ around_filters << filter unless around_filters.any? { |f| f.callback_method == filter.callback_method }
66
+ end
67
+
30
68
  def around_filters
31
69
  @_around_filters ||= []
32
70
  end
@@ -95,7 +133,11 @@ module ActionSubscriber
95
133
  final_block = Proc.new { subscriber_instance.public_send(action) }
96
134
 
97
135
  first_proc = around_filters.reverse.reduce(final_block) do |block, filter|
98
- Proc.new { subscriber_instance.send(filter, &block) }
136
+ if filter.matches(action)
137
+ Proc.new { subscriber_instance.send(filter.callback_method, &block) }
138
+ else
139
+ block
140
+ end
99
141
  end
100
142
  first_proc.call
101
143
  end
@@ -4,7 +4,8 @@ module ActionSubscriber
4
4
  include ::ActionSubscriber::Logging
5
5
 
6
6
  def cancel_consumers!
7
- march_hare_consumers.each(&:cancel)
7
+ # Cancel any non-cancelled consumers.
8
+ march_hare_consumers.reject(&:cancelled?).each(&:cancel)
8
9
  ::ActionSubscriber::ThreadPools.threadpools.each do |name, threadpool|
9
10
  threadpool.shutdown
10
11
  end
@@ -26,33 +27,50 @@ module ActionSubscriber
26
27
 
27
28
  def start_subscribers!
28
29
  subscriptions.each do |subscription|
29
- route = subscription[:route]
30
- queue = subscription[:queue]
31
- queue.channel.prefetch = route.prefetch if route.acknowledgements?
32
- threadpool = ::ActionSubscriber::ThreadPools.threadpools.fetch(route.threadpool_name)
33
- consumer = queue.subscribe(route.queue_subscription_options) do |metadata, encoded_payload|
34
- ::ActiveSupport::Notifications.instrument "received_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
35
- properties = {
36
- :action => route.action,
37
- :channel => queue.channel,
38
- :content_type => metadata.content_type,
39
- :delivery_tag => metadata.delivery_tag,
40
- :exchange => metadata.exchange,
41
- :headers => _normalized_headers(metadata),
42
- :message_id => metadata.message_id,
43
- :routing_key => metadata.routing_key,
44
- :queue => queue.name,
45
- :uses_acknowledgements => route.acknowledgements?,
46
- }
47
- env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
48
- run_env(env, threadpool)
30
+ start_subscriber_for_subscription(subscription)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def start_subscriber_for_subscription(subscription)
37
+ route = subscription[:route]
38
+ queue = subscription[:queue]
39
+ queue.channel.prefetch = route.prefetch if route.acknowledgements?
40
+ threadpool = ::ActionSubscriber::ThreadPools.threadpools.fetch(route.threadpool_name)
41
+ opts = route.queue_subscription_options
42
+
43
+ if ::ActionSubscriber.configuration.resubscribe_on_consumer_cancellation
44
+ # Add cancellation callback to rebuild subscriber on cancel.
45
+ opts[:on_cancellation] = lambda do |the_consumer|
46
+ ::ActionSubscriber.logger.warn "Cancelation received for queue consumer: #{queue.name}, rebuilding subscription..."
47
+ march_hare_consumers.delete(the_consumer)
48
+ queue.channel.close
49
+ queue = subscription[:queue] = setup_queue(route)
50
+ start_subscriber_for_subscription(subscription)
49
51
  end
52
+ end
50
53
 
51
- march_hare_consumers << consumer
54
+ consumer = queue.subscribe(opts) do |metadata, encoded_payload|
55
+ ::ActiveSupport::Notifications.instrument "received_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
56
+ properties = {
57
+ :action => route.action,
58
+ :channel => queue.channel,
59
+ :content_type => metadata.content_type,
60
+ :delivery_tag => metadata.delivery_tag,
61
+ :exchange => metadata.exchange,
62
+ :headers => _normalized_headers(metadata),
63
+ :message_id => metadata.message_id,
64
+ :routing_key => metadata.routing_key,
65
+ :queue => queue.name,
66
+ :uses_acknowledgements => route.acknowledgements?,
67
+ }
68
+ env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
69
+ run_env(env, threadpool)
52
70
  end
53
- end
54
71
 
55
- private
72
+ march_hare_consumers << consumer
73
+ end
56
74
 
57
75
  def setup_queue(route)
58
76
  channel = ::ActionSubscriber::RabbitConnection.with_connection{|connection| connection.create_channel }
@@ -42,7 +42,7 @@ module ActionSubscriber
42
42
  @has_been_nacked = false
43
43
  @has_been_rejected = false
44
44
  @headers = properties.fetch(:headers, {})
45
- @message_id = properties.fetch(:message_id, ::SecureRandom.hex(3))
45
+ @message_id = properties[:message_id].presence || ::SecureRandom.hex(3)
46
46
  @queue = properties.fetch(:queue)
47
47
  @routing_key = properties.fetch(:routing_key)
48
48
  @subscriber = subscriber
@@ -30,9 +30,22 @@ module ActionSubscriber
30
30
  ::MarchHare::ThreadPools.fixed_of_size(options[:threadpool_size])
31
31
  end
32
32
  connection = ::MarchHare.connect(options)
33
+ connection.on_blocked do |reason|
34
+ on_blocked(reason)
35
+ end
36
+ connection.on_unblocked do
37
+ on_unblocked
38
+ end
39
+ connection
33
40
  else
34
41
  connection = ::Bunny.new(options)
35
42
  connection.start
43
+ connection.on_blocked do |blocked_message|
44
+ on_blocked(blocked_message.reason)
45
+ end
46
+ connection.on_unblocked do
47
+ on_unblocked
48
+ end
36
49
  connection
37
50
  end
38
51
  end
@@ -59,5 +72,15 @@ module ActionSubscriber
59
72
  }
60
73
  end
61
74
  private_class_method :connection_options
75
+
76
+ def self.on_blocked(reason)
77
+ ::ActiveSupport::Notifications.instrument("connection_blocked.action_subscriber", :reason => reason)
78
+ end
79
+ private_class_method :on_blocked
80
+
81
+ def self.on_unblocked
82
+ ::ActiveSupport::Notifications.instrument("connection_unblocked.action_subscriber")
83
+ end
84
+ private_class_method :on_unblocked
62
85
  end
63
86
  end
@@ -1,3 +1,3 @@
1
1
  module ActionSubscriber
2
- VERSION = "5.1.4.pre0"
2
+ VERSION = "5.2.2"
3
3
  end
@@ -33,7 +33,7 @@ describe "subscriber filters", :integration => true do
33
33
  let(:subscriber) { InstaSubscriber }
34
34
 
35
35
  it "does not allow an around filter to be pushed on twice" do
36
- expect(InstaSubscriber.around_filters).to eq([:whisper, :yell])
36
+ expect(InstaSubscriber.around_filters.map(&:callback_method)).to eq([:whisper, :yell])
37
37
  end
38
38
 
39
39
  it "runs multiple around filters" do
@@ -46,3 +46,89 @@ describe "subscriber filters", :integration => true do
46
46
  end
47
47
  end
48
48
  end
49
+
50
+ class OptionsSubscriber < ActionSubscriber::Base
51
+ around_filter :whisper, :if => [:primero, :segundo]
52
+ around_filter :yell, :if => [:primero]
53
+ around_filter :gossip, :unless => [:private_action]
54
+ around_filter :everybody
55
+
56
+ def primero
57
+ $messages << payload
58
+ end
59
+
60
+ def private_action
61
+ $messages << payload
62
+ end
63
+
64
+ def segundo
65
+ $messages << payload
66
+ end
67
+
68
+ private
69
+
70
+ def everybody
71
+ $messages << :everybody_before
72
+ yield
73
+ $messages << :everybody_after
74
+ end
75
+
76
+ def gossip
77
+ $messages << :gossip_before
78
+ yield
79
+ $messages << :gossip_after
80
+ end
81
+
82
+ def whisper
83
+ $messages << :whisper_before
84
+ yield
85
+ $messages << :whisper_after
86
+ end
87
+
88
+ def yell
89
+ $messages << :yell_before
90
+ yield
91
+ $messages << :yell_after
92
+ end
93
+ end
94
+
95
+ describe "subscriber filters with conditions", :integration => true do
96
+ let(:draw_routes) do
97
+ ::ActionSubscriber.draw_routes do
98
+ default_routes_for OptionsSubscriber
99
+ end
100
+ end
101
+ let(:subscriber) { OptionsSubscriber }
102
+
103
+ context "honors conditions" do
104
+ it "runs yell" do
105
+ $messages = []
106
+ ::ActionSubscriber.start_subscribers!
107
+ ::ActivePublisher.publish("options.primero", "Howdy!", "events")
108
+
109
+ verify_expectation_within(1.0) do
110
+ expect($messages).to eq [:whisper_before, :yell_before, :gossip_before, :everybody_before, "Howdy!", :everybody_after, :gossip_after, :yell_after, :whisper_after]
111
+ end
112
+ end
113
+
114
+ it "doesn't yell" do
115
+ $messages = []
116
+ ::ActionSubscriber.start_subscribers!
117
+ ::ActivePublisher.publish("options.segundo", "Howdy!", "events")
118
+
119
+ verify_expectation_within(1.0) do
120
+ expect($messages).to eq [:whisper_before, :gossip_before, :everybody_before, "Howdy!", :everybody_after, :gossip_after, :whisper_after]
121
+ end
122
+ end
123
+
124
+ it "doesn't gossip" do
125
+ $messages = []
126
+ ::ActionSubscriber.start_subscribers!
127
+ ::ActivePublisher.publish("options.private_action", "Howdy!", "events")
128
+
129
+ verify_expectation_within(1.0) do
130
+ expect($messages).to eq [:everybody_before, "Howdy!", :everybody_after]
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,83 @@
1
+ require "spec_helper"
2
+ require "rabbitmq/http/client"
3
+
4
+ class YoloSubscriber < ActionSubscriber::Base
5
+ def created
6
+ $messages << payload
7
+ end
8
+ end
9
+
10
+ describe "Automatically handles consumer cancellation", :integration => true, :slow => true do
11
+ let(:draw_routes) do
12
+ ::ActionSubscriber.draw_routes do
13
+ default_routes_for ::YoloSubscriber
14
+ end
15
+ end
16
+ let(:http_client) { ::RabbitMQ::HTTP::Client.new("http://127.0.0.1:15672") }
17
+ let(:subscriber) { ::YoloSubscriber }
18
+
19
+ it "resubscribes on cancellation" do
20
+ ::ActionSubscriber::start_subscribers!
21
+ ::ActivePublisher.publish("yolo.created", "First", "events")
22
+ verify_expectation_within(5.0) do
23
+ expect($messages).to eq(::Set.new(["First"]))
24
+ end
25
+
26
+ consumers = rabbit_consumers.dup
27
+
28
+ # Signal a cancellation event to all subscribers.
29
+ delete_all_queues!
30
+
31
+ # Give consumers a chance to restart.
32
+ sleep 2.0
33
+
34
+ expect(rabbit_consumers).to_not eq(consumers)
35
+
36
+ ::ActivePublisher.publish("yolo.created", "Second", "events")
37
+ verify_expectation_within(5.0) do
38
+ expect($messages).to eq(Set.new(["First", "Second"]))
39
+ end
40
+ end
41
+
42
+ context "when resubscribe on consumer cancellation is disabled" do
43
+ before do
44
+ allow(::ActionSubscriber.configuration).to receive(:resubscribe_on_consumer_cancellation).and_return(false)
45
+ end
46
+
47
+ it "does not resubscribe on cancellation" do
48
+ ::ActionSubscriber::start_subscribers!
49
+ ::ActivePublisher.publish("yolo.created", "First", "events")
50
+ verify_expectation_within(5.0) do
51
+ expect($messages).to eq(::Set.new(["First"]))
52
+ end
53
+
54
+ consumers = rabbit_consumers.dup
55
+
56
+ # Signal a cancellation event to all subscribers.
57
+ delete_all_queues!
58
+
59
+ # Give consumers a chance to restart.
60
+ sleep 2.0
61
+
62
+ # Verify the consumers did not change.
63
+ expect(rabbit_consumers).to eq(consumers)
64
+
65
+ ::ActivePublisher.publish("yolo.created", "Second", "events")
66
+
67
+ # Force sleep 2 seconds to ensure a resubscribe did not happen and messages were not processed.
68
+ sleep 2.0
69
+ expect($messages).to eq(Set.new(["First"]))
70
+ end
71
+ end
72
+
73
+ def rabbit_consumers
74
+ route_set = ::ActionSubscriber.send(:route_set)
75
+ route_set.try(:bunny_consumers) || route_set.try(:march_hare_consumers)
76
+ end
77
+
78
+ def delete_all_queues!
79
+ http_client.list_queues.each do |queue|
80
+ http_client.delete_queue(queue.vhost, queue.name)
81
+ end
82
+ end
83
+ end
@@ -24,6 +24,13 @@ describe ::ActionSubscriber::Configuration do
24
24
  ::ActionSubscriber::Configuration.configure_from_yaml_and_cli({}, true)
25
25
  end
26
26
  end
27
+
28
+ it "can override a true value with a false value" do
29
+ expect(::ActionSubscriber.configuration.verify_peer).to eq(true)
30
+ expect(::ActionSubscriber.configuration).to receive(:verify_peer=).with(false).and_call_original
31
+ ::ActionSubscriber::Configuration.configure_from_yaml_and_cli({"verify_peer" => false}, true)
32
+ expect(::ActionSubscriber.configuration.verify_peer).to eq(false)
33
+ end
27
34
  end
28
35
 
29
36
  describe "add_decoder" do
@@ -0,0 +1,63 @@
1
+ require "spec_helper"
2
+
3
+ describe ::ActionSubscriber::RabbitConnection do
4
+ let(:reason) { "low on disk" }
5
+
6
+ before { ActionSubscriber.draw_routes {} }
7
+
8
+ context "on_block" do
9
+ if ::RUBY_PLATFORM == "java"
10
+ def trigger_mocked_blocking_event(connection, reason)
11
+ amqp_message = ::Java::ComRabbitmqClient::AMQP::Connection::Blocked::Builder.new.
12
+ reason(reason).build
13
+ amq_command = ::Java::ComRabbitmqClientImpl::AMQCommand.new(amqp_message)
14
+
15
+ connection.send(:processControlCommand, amq_command)
16
+ end
17
+ else
18
+ def trigger_mocked_blocking_event(connection, reason)
19
+ connection.send(:handle_frame, 0, ::AMQ::Protocol::Connection::Blocked.new(reason))
20
+ end
21
+ end
22
+
23
+ it "can deliver an on_blocked message" do
24
+ expect(::ActiveSupport::Notifications).to receive(:instrument).
25
+ with("connection_blocked.action_subscriber", :reason => reason)
26
+
27
+ described_class.with_connection do |connection|
28
+ # NOTE: Trigger the receiving of a blocked message from the broker.
29
+ # It's a bit of a hack but it is a more realistic test without changing
30
+ # memory alarms.
31
+ trigger_mocked_blocking_event(connection, reason)
32
+ end
33
+ end
34
+ end
35
+
36
+ context "on_unblocked" do
37
+ if ::RUBY_PLATFORM == "java"
38
+ def trigger_mocked_unblocked_event(connection, reason)
39
+ amqp_message = ::Java::ComRabbitmqClient::AMQP::Connection::Unblocked::Builder.new.
40
+ build
41
+ amq_command = ::Java::ComRabbitmqClientImpl::AMQCommand.new(amqp_message)
42
+
43
+ connection.send(:processControlCommand, amq_command)
44
+ end
45
+ else
46
+ def trigger_mocked_unblocked_event(connection, reason)
47
+ connection.send(:handle_frame, 0, ::AMQ::Protocol::Connection::Unblocked.new)
48
+ end
49
+ end
50
+
51
+ it "can deliver an on_unblocked message" do
52
+ expect(::ActiveSupport::Notifications).to receive(:instrument).
53
+ with("connection_unblocked.action_subscriber")
54
+
55
+ described_class.with_connection do |connection|
56
+ # NOTE: Trigger the receiving of an unblocked message from the broker.
57
+ # It's a bit of a hack but it is a more realistic test without changing
58
+ # memory alarms.
59
+ trigger_mocked_unblocked_event(connection, reason)
60
+ end
61
+ end
62
+ end
63
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_subscriber
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.4.pre0
4
+ version: 5.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Stien
@@ -9,10 +9,10 @@ authors:
9
9
  - Brandon Dewitt
10
10
  - Devin Christensen
11
11
  - Michael Ries
12
- autorequire:
12
+ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2018-11-30 00:00:00.000000000 Z
15
+ date: 2020-07-29 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport
@@ -258,6 +258,7 @@ files:
258
258
  - spec/integration/at_most_once_spec.rb
259
259
  - spec/integration/automatic_reconnect_spec.rb
260
260
  - spec/integration/basic_subscriber_spec.rb
261
+ - spec/integration/consumer_cancellation_spec.rb
261
262
  - spec/integration/custom_actions_spec.rb
262
263
  - spec/integration/custom_headers_spec.rb
263
264
  - spec/integration/decoding_payloads_spec.rb
@@ -272,6 +273,7 @@ files:
272
273
  - spec/lib/action_subscriber/middleware/error_handler_spec.rb
273
274
  - spec/lib/action_subscriber/middleware/router_spec.rb
274
275
  - spec/lib/action_subscriber/middleware/runner_spec.rb
276
+ - spec/lib/action_subscriber/rabbit_connection_spec.rb
275
277
  - spec/lib/action_subscriber/router_spec.rb
276
278
  - spec/lib/action_subscriber/subscribable_spec.rb
277
279
  - spec/spec_helper.rb
@@ -281,7 +283,7 @@ homepage: https://github.com/mxenabled/action_subscriber
281
283
  licenses:
282
284
  - MIT
283
285
  metadata: {}
284
- post_install_message:
286
+ post_install_message:
285
287
  rdoc_options: []
286
288
  require_paths:
287
289
  - lib
@@ -292,13 +294,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
292
294
  version: '0'
293
295
  required_rubygems_version: !ruby/object:Gem::Requirement
294
296
  requirements:
295
- - - ">"
297
+ - - ">="
296
298
  - !ruby/object:Gem::Version
297
- version: 1.3.1
299
+ version: '0'
298
300
  requirements: []
299
- rubyforge_project:
300
- rubygems_version: 2.7.6
301
- signing_key:
301
+ rubygems_version: 3.1.2
302
+ signing_key:
302
303
  specification_version: 4
303
304
  summary: ActionSubscriber is a DSL that allows a rails app to consume messages from
304
305
  a RabbitMQ broker.
@@ -308,6 +309,7 @@ test_files:
308
309
  - spec/integration/at_most_once_spec.rb
309
310
  - spec/integration/automatic_reconnect_spec.rb
310
311
  - spec/integration/basic_subscriber_spec.rb
312
+ - spec/integration/consumer_cancellation_spec.rb
311
313
  - spec/integration/custom_actions_spec.rb
312
314
  - spec/integration/custom_headers_spec.rb
313
315
  - spec/integration/decoding_payloads_spec.rb
@@ -322,6 +324,7 @@ test_files:
322
324
  - spec/lib/action_subscriber/middleware/error_handler_spec.rb
323
325
  - spec/lib/action_subscriber/middleware/router_spec.rb
324
326
  - spec/lib/action_subscriber/middleware/runner_spec.rb
327
+ - spec/lib/action_subscriber/rabbit_connection_spec.rb
325
328
  - spec/lib/action_subscriber/router_spec.rb
326
329
  - spec/lib/action_subscriber/subscribable_spec.rb
327
330
  - spec/spec_helper.rb