action_subscriber 2.5.0.pre2 → 3.0.0.pre1

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/action_subscriber.gemspec +1 -0
  3. data/lib/action_subscriber/babou.rb +2 -29
  4. data/lib/action_subscriber/base.rb +0 -4
  5. data/lib/action_subscriber/bunny/subscriber.rb +14 -4
  6. data/lib/action_subscriber/configuration.rb +1 -11
  7. data/lib/action_subscriber/default_routing.rb +6 -4
  8. data/lib/action_subscriber/march_hare/subscriber.rb +14 -4
  9. data/lib/action_subscriber/message_retry.rb +1 -1
  10. data/lib/action_subscriber/middleware/env.rb +3 -1
  11. data/lib/action_subscriber/middleware/error_handler.rb +11 -4
  12. data/lib/action_subscriber/rabbit_connection.rb +23 -34
  13. data/lib/action_subscriber/route.rb +5 -1
  14. data/lib/action_subscriber/route_set.rb +12 -11
  15. data/lib/action_subscriber/router.rb +13 -2
  16. data/lib/action_subscriber/version.rb +1 -1
  17. data/lib/action_subscriber.rb +11 -24
  18. data/spec/integration/around_filters_spec.rb +1 -1
  19. data/spec/integration/at_least_once_spec.rb +1 -1
  20. data/spec/integration/at_most_once_spec.rb +1 -1
  21. data/spec/integration/automatic_reconnect_spec.rb +3 -4
  22. data/spec/integration/basic_subscriber_spec.rb +2 -2
  23. data/spec/integration/custom_actions_spec.rb +1 -1
  24. data/spec/integration/custom_headers_spec.rb +2 -2
  25. data/spec/integration/decoding_payloads_spec.rb +2 -2
  26. data/spec/integration/manual_acknowledgement_spec.rb +1 -1
  27. data/spec/integration/multiple_connections_spec.rb +36 -0
  28. data/spec/integration/multiple_threadpools_spec.rb +3 -3
  29. data/spec/lib/action_subscriber/configuration_spec.rb +1 -5
  30. data/spec/spec_helper.rb +7 -4
  31. metadata +18 -14
  32. data/lib/action_subscriber/publisher/async/in_memory_adapter.rb +0 -153
  33. data/lib/action_subscriber/publisher/async.rb +0 -31
  34. data/lib/action_subscriber/publisher.rb +0 -46
  35. data/lib/action_subscriber/synchronizer.rb +0 -15
  36. data/spec/integration/inferred_routes_spec.rb +0 -53
  37. data/spec/lib/action_subscriber/publisher/async/in_memory_adapter_spec.rb +0 -135
  38. data/spec/lib/action_subscriber/publisher/async_spec.rb +0 -40
  39. data/spec/lib/action_subscriber/publisher_spec.rb +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 85dc20de7aa4e917f499156bb94d4b2e40b9ed12
4
- data.tar.gz: 7f34bea3b45e1e230cbc55e4e432540094c6241a
3
+ metadata.gz: b0a848297f91f557f43e6240545866aaad495d17
4
+ data.tar.gz: 0fd512e453740a0ad0e34f1f42ddef7ab5ac240f
5
5
  SHA512:
6
- metadata.gz: c2b3f863edc1609bc43f403b519cb05c62a7b4dc7e7b8f2048d076fdb7d4523271bd742e3006f67e50b34360c2ac357dc773771e1e0b6d321450e941effed54f
7
- data.tar.gz: a4261aa2255ad0eb865a1d3e64b0249ea0fac3b91a103301f337ca715777913ff7e1e2a1fe13b6f69a2b2cfcf1bc2d8fb87018c0653fc2ec0e73738cda6e594c
6
+ metadata.gz: 6d30b59daffa7e89a4c48eb3044a65af90804d91b3c0991e3dd0899b9a20944532878bc6327684577d05c11b9017edfb233bbd251daa42dff9a50d614f4701da
7
+ data.tar.gz: df4cf38fe9cbfed26adcc53e43823348726176cc387ccaa46d22274099182198aa1c2d1fcd1c7e341d87dd6e4f1a88e24702788a41c9955e8a2161a880459d56
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_dependency 'middleware'
31
31
  spec.add_dependency 'thor'
32
32
 
33
+ spec.add_development_dependency "active_publisher", "~> 0.1.5"
33
34
  spec.add_development_dependency "activerecord", ">= 3.2"
34
35
  spec.add_development_dependency "bundler", ">= 1.6"
35
36
  spec.add_development_dependency "pry-nav"
@@ -7,7 +7,7 @@ module ActionSubscriber
7
7
  def self.auto_pop!
8
8
  @pop_mode = true
9
9
  reload_active_record
10
- load_subscribers unless subscribers_loaded?
10
+ ::ActionSubscriber.setup_default_connection!
11
11
  sleep_time = ::ActionSubscriber.configuration.pop_interval.to_i / 1000.0
12
12
 
13
13
  ::ActionSubscriber.start_queues
@@ -30,7 +30,7 @@ module ActionSubscriber
30
30
  def self.start_subscribers
31
31
  @prowl_mode = true
32
32
  reload_active_record
33
- load_subscribers unless subscribers_loaded?
33
+ ::ActionSubscriber.setup_default_connection!
34
34
 
35
35
  ::ActionSubscriber.start_subscribers
36
36
  logger.info "Action Subscriber connected"
@@ -45,29 +45,6 @@ module ActionSubscriber
45
45
  !!@prowl_mode
46
46
  end
47
47
 
48
- def self.load_subscribers
49
- subscription_paths = ["subscriptions", "subscribers"]
50
- path_prefixes = ["lib", "app"]
51
- cloned_paths = subscription_paths.dup
52
-
53
- path_prefixes.each do |prefix|
54
- cloned_paths.each { |path| subscription_paths << "#{prefix}/#{path}" }
55
- end
56
-
57
- absolute_subscription_paths = subscription_paths.map{ |path| ::File.expand_path(path) }
58
- absolute_subscription_paths.each do |path|
59
- if ::File.exists?("#{path}.rb")
60
- load("#{path}.rb")
61
- end
62
-
63
- if ::File.directory?(path)
64
- ::Dir[::File.join(path, "**", "*.rb")].sort.each do |file|
65
- load file
66
- end
67
- end
68
- end
69
- end
70
-
71
48
  def self.logger
72
49
  ::ActionSubscriber::Logging.logger
73
50
  end
@@ -108,9 +85,5 @@ module ActionSubscriber
108
85
 
109
86
  puts "threadpool empty. Shutting down"
110
87
  end
111
-
112
- def self.subscribers_loaded?
113
- !::ActionSubscriber::Base.inherited_classes.empty?
114
- end
115
88
  end
116
89
  end
@@ -26,10 +26,6 @@ module ActionSubscriber
26
26
  # Class Methods
27
27
  #
28
28
 
29
- def self.connection
30
- ::ActionSubscriber::RabbitConnection.subscriber_connection
31
- end
32
-
33
29
  # Inherited callback, save a reference to our descendents
34
30
  #
35
31
  def self.inherited(klass)
@@ -20,7 +20,9 @@ module ActionSubscriber
20
20
  # of times we will pop each time we poll the broker
21
21
  times_to_pop = [::ActionSubscriber::Threadpool.ready_size, ::ActionSubscriber.config.times_to_pop].min
22
22
  times_to_pop.times do
23
- queues.each do |route, queue|
23
+ subscriptions.each do |subscription|
24
+ route = subscription[:route]
25
+ queue = subscription[:queue]
24
26
  # Handle busy checks on a per threadpool basis
25
27
  next if route.threadpool.busy?
26
28
 
@@ -29,7 +31,6 @@ module ActionSubscriber
29
31
  ::ActiveSupport::Notifications.instrument "popped_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
30
32
  properties = {
31
33
  :action => route.action,
32
- :channel => queue.channel,
33
34
  :content_type => properties[:content_type],
34
35
  :delivery_tag => delivery_info.delivery_tag,
35
36
  :exchange => delivery_info.exchange,
@@ -45,7 +46,9 @@ module ActionSubscriber
45
46
  end
46
47
 
47
48
  def auto_subscribe!
48
- queues.each do |route, queue|
49
+ subscriptions.each do |subscription|
50
+ route = subscription[:route]
51
+ queue = subscription[:queue]
49
52
  channel = queue.channel
50
53
  channel.prefetch(route.prefetch) if route.acknowledgements?
51
54
  consumer = ::Bunny::Consumer.new(channel, queue, channel.generate_consumer_tag, !route.acknowledgements?)
@@ -63,7 +66,7 @@ module ActionSubscriber
63
66
  :queue => queue.name,
64
67
  }
65
68
  env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
66
- enqueue_env(route.threadpool, env)
69
+ run_env(env)
67
70
  end
68
71
  bunny_consumers << consumer
69
72
  queue.subscribe_with(consumer)
@@ -80,6 +83,13 @@ module ActionSubscriber
80
83
  end
81
84
  end
82
85
  end
86
+
87
+ def run_env(env)
88
+ logger.info "RECEIVED #{env.message_id} from #{env.queue}"
89
+ ::ActiveSupport::Notifications.instrument "process_event.action_subscriber", :subscriber => env.subscriber.to_s, :routing_key => env.routing_key, :queue => env.queue do
90
+ ::ActionSubscriber.config.middleware.call(env)
91
+ end
92
+ end
83
93
  end
84
94
  end
85
95
  end
@@ -4,10 +4,6 @@ require "action_subscriber/uri"
4
4
  module ActionSubscriber
5
5
  class Configuration
6
6
  attr_accessor :allow_low_priority_methods,
7
- :async_publisher,
8
- :async_publisher_drop_messages_when_queue_full,
9
- :async_publisher_max_queue_size,
10
- :async_publisher_supervisor_interval,
11
7
  :decoder,
12
8
  :default_exchange,
13
9
  :error_handler,
@@ -19,7 +15,6 @@ module ActionSubscriber
19
15
  :pop_interval,
20
16
  :port,
21
17
  :prefetch,
22
- :publisher_confirms,
23
18
  :seconds_to_wait_for_graceful_shutdown,
24
19
  :username,
25
20
  :threadpool_size,
@@ -31,10 +26,6 @@ module ActionSubscriber
31
26
 
32
27
  DEFAULTS = {
33
28
  :allow_low_priority_methods => false,
34
- :async_publisher => 'memory',
35
- :async_publisher_drop_messages_when_queue_full => false,
36
- :async_publisher_max_queue_size => 1_000_000,
37
- :async_publisher_supervisor_interval => 200, # in milliseconds
38
29
  :default_exchange => 'events',
39
30
  :heartbeat => 5,
40
31
  :host => 'localhost',
@@ -42,8 +33,7 @@ module ActionSubscriber
42
33
  :mode => 'subscribe',
43
34
  :pop_interval => 100, # in milliseconds
44
35
  :port => 5672,
45
- :prefetch => 5,
46
- :publisher_confirms => false,
36
+ :prefetch => 2,
47
37
  :seconds_to_wait_for_graceful_shutdown => 30,
48
38
  :threadpool_size => 8,
49
39
  :timeout => 1,
@@ -1,19 +1,21 @@
1
1
  module ActionSubscriber
2
2
  module DefaultRouting
3
- def routes
3
+ def routes(route_settings)
4
4
  @routes ||= begin
5
5
  routes = []
6
6
  exchange_names.each do |exchange_name|
7
7
  subscribable_methods.each do |method_name|
8
- routes << ActionSubscriber::Route.new({
8
+ settings = {
9
9
  acknowledgements: acknowledge_messages?,
10
10
  action: method_name,
11
- durable: false,
11
+ durable: false,
12
12
  exchange: exchange_name,
13
13
  routing_key: routing_key_name_for_method(method_name),
14
14
  subscriber: self,
15
15
  queue: queue_name_for_method(method_name),
16
- })
16
+ }
17
+ settings.merge!(route_settings)
18
+ routes << ActionSubscriber::Route.new(settings)
17
19
  end
18
20
  end
19
21
  routes
@@ -18,7 +18,9 @@ module ActionSubscriber
18
18
  # of times we will pop each time we poll the broker
19
19
  times_to_pop = [::ActionSubscriber::Threadpool.ready_size, ::ActionSubscriber.config.times_to_pop].min
20
20
  times_to_pop.times do
21
- queues.each do |route,queue|
21
+ subscriptions.each do |subscription|
22
+ route = subscription[:route]
23
+ queue = subscription[:queue]
22
24
  # Handle busy checks on a per threadpool basis
23
25
  next if route.threadpool.busy?
24
26
 
@@ -27,7 +29,6 @@ module ActionSubscriber
27
29
  ::ActiveSupport::Notifications.instrument "popped_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
28
30
  properties = {
29
31
  :action => route.action,
30
- :channel => queue.channel,
31
32
  :content_type => metadata.content_type,
32
33
  :delivery_tag => metadata.delivery_tag,
33
34
  :exchange => metadata.exchange,
@@ -46,7 +47,9 @@ module ActionSubscriber
46
47
  end
47
48
 
48
49
  def auto_subscribe!
49
- queues.each do |route,queue|
50
+ subscriptions.each do |subscription|
51
+ route = subscription[:route]
52
+ queue = subscription[:queue]
50
53
  queue.channel.prefetch = route.prefetch if route.acknowledgements?
51
54
  consumer = queue.subscribe(route.queue_subscription_options) do |metadata, encoded_payload|
52
55
  ::ActiveSupport::Notifications.instrument "received_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
@@ -62,7 +65,7 @@ module ActionSubscriber
62
65
  :queue => queue.name,
63
66
  }
64
67
  env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
65
- enqueue_env(route.threadpool, env)
68
+ run_env(env)
66
69
  end
67
70
 
68
71
  march_hare_consumers << consumer
@@ -84,6 +87,13 @@ module ActionSubscriber
84
87
  end
85
88
  end
86
89
 
90
+ def run_env(env)
91
+ logger.info "RECEIVED #{env.message_id} from #{env.queue}"
92
+ ::ActiveSupport::Notifications.instrument "process_event.action_subscriber", :subscriber => env.subscriber.to_s, :routing_key => env.routing_key, :queue => env.queue do
93
+ ::ActionSubscriber.config.middleware.call(env)
94
+ end
95
+ end
96
+
87
97
  def _normalized_headers(metadata)
88
98
  return {} unless metadata.headers
89
99
  metadata.headers.each_with_object({}) do |(header,value), hash|
@@ -46,7 +46,7 @@ module ActionSubscriber
46
46
  end
47
47
 
48
48
  def self.with_exchange(env, ttl, retry_queue_name)
49
- channel = RabbitConnection.subscriber_connection.create_channel
49
+ channel = RabbitConnection.with_connection(:default){|connection| connection.create_channel}
50
50
  begin
51
51
  channel.confirm_select
52
52
  # an empty string is the default exchange [see bunny docs](http://rubybunny.info/articles/exchanges.html#default_exchange)
@@ -28,7 +28,7 @@ module ActionSubscriber
28
28
  # :routing_key => String
29
29
  def initialize(subscriber, encoded_payload, properties)
30
30
  @action = properties.fetch(:action)
31
- @channel = properties.fetch(:channel)
31
+ @channel = properties[:channel]
32
32
  @content_type = properties.fetch(:content_type)
33
33
  @delivery_tag = properties.fetch(:delivery_tag)
34
34
  @encoded_payload = encoded_payload
@@ -41,12 +41,14 @@ module ActionSubscriber
41
41
  end
42
42
 
43
43
  def acknowledge
44
+ fail ::RuntimeError, "you can't acknowledge messages under the polling API" unless @channel
44
45
  acknowledge_multiple_messages = false
45
46
  @channel.ack(@delivery_tag, acknowledge_multiple_messages)
46
47
  true
47
48
  end
48
49
 
49
50
  def reject
51
+ fail ::RuntimeError, "you can't acknowledge messages under the polling API" unless @channel
50
52
  requeue_message = true
51
53
  @channel.reject(@delivery_tag, requeue_message)
52
54
  true
@@ -8,10 +8,17 @@ module ActionSubscriber
8
8
  end
9
9
 
10
10
  def call(env)
11
- @app.call(env)
12
- rescue => error
13
- logger.error "FAILED #{env.message_id}"
14
- ::ActionSubscriber.configuration.error_handler.call(error, env.to_h)
11
+ # This insulates the connection thread from errors that are raised by the error_handle or
12
+ # exceptions that don't fall under StandardError (which are not caught by `rescue => error`)
13
+ new_thread = ::Thread.new do
14
+ begin
15
+ @app.call(env)
16
+ rescue => error
17
+ logger.error "FAILED #{env.message_id}"
18
+ ::ActionSubscriber.configuration.error_handler.call(error, env.to_h)
19
+ end
20
+ end
21
+ ::Thread.pass while new_thread.alive?
15
22
  end
16
23
  end
17
24
  end
@@ -3,57 +3,40 @@ require 'thread'
3
3
  module ActionSubscriber
4
4
  module RabbitConnection
5
5
  SUBSCRIBER_CONNECTION_MUTEX = ::Mutex.new
6
- PUBLISHER_CONNECTION_MUTEX = ::Mutex.new
7
6
  NETWORK_RECOVERY_INTERVAL = 1.freeze
8
7
 
9
- def self.publisher_connected?
10
- publisher_connection.try(:connected?)
11
- end
12
-
13
- def self.publisher_connection
8
+ def self.setup_connection(name, settings)
14
9
  SUBSCRIBER_CONNECTION_MUTEX.synchronize do
15
- return @publisher_connection if @publisher_connection
16
- @publisher_connection = create_connection
17
- end
18
- end
19
-
20
- def self.publisher_disconnect!
21
- SUBSCRIBER_CONNECTION_MUTEX.synchronize do
22
- if @publisher_connection && @publisher_connection.connected?
23
- @publisher_connection.close
24
- end
25
-
26
- @publisher_connection = nil
10
+ fail ArgumentError, "a #{name} connection already exists" if subscriber_connections[name]
11
+ subscriber_connections[name] = create_connection(settings)
27
12
  end
28
13
  end
29
14
 
30
15
  def self.subscriber_connected?
31
- subscriber_connection.try(:connected?)
16
+ subscriber_connections.all?{|_name, connection| connection.connected?}
32
17
  end
33
18
 
34
- def self.subscriber_connection
19
+ def self.subscriber_disconnect!
35
20
  SUBSCRIBER_CONNECTION_MUTEX.synchronize do
36
- return @subscriber_connection if @subscriber_connection
37
- @subscriber_connection = create_connection
21
+ subscriber_connections.each{|_name, connection| connection.close}
22
+ @subscriber_connections = []
38
23
  end
39
24
  end
40
25
 
41
- def self.subscriber_disconnect!
26
+ def self.with_connection(name)
42
27
  SUBSCRIBER_CONNECTION_MUTEX.synchronize do
43
- if @subscriber_connection && @subscriber_connection.connected?
44
- @subscriber_connection.close
45
- end
46
-
47
- @subscriber_connection = nil
28
+ fail ArgumentError, "there is no connection named #{name}" unless subscriber_connections[name]
29
+ yield(subscriber_connections[name])
48
30
  end
49
31
  end
50
32
 
51
33
  # Private API
52
- def self.create_connection
34
+ def self.create_connection(settings)
35
+ options = connection_options.merge(settings)
53
36
  if ::RUBY_PLATFORM == "java"
54
- connection = ::MarchHare.connect(connection_options)
37
+ connection = ::MarchHare.connect(options)
55
38
  else
56
- connection = ::Bunny.new(connection_options)
39
+ connection = ::Bunny.new(options)
57
40
  connection.start
58
41
  connection
59
42
  end
@@ -62,18 +45,24 @@ module ActionSubscriber
62
45
 
63
46
  def self.connection_options
64
47
  {
48
+ :automatically_recover => true,
65
49
  :continuation_timeout => ::ActionSubscriber.configuration.timeout * 1_000.0, #convert sec to ms
66
50
  :heartbeat => ::ActionSubscriber.configuration.heartbeat,
67
51
  :hosts => ::ActionSubscriber.configuration.hosts,
52
+ :network_recovery_interval => NETWORK_RECOVERY_INTERVAL,
68
53
  :pass => ::ActionSubscriber.configuration.password,
69
54
  :port => ::ActionSubscriber.configuration.port,
55
+ :recover_from_connection_close => true,
56
+ :threadpool_size => ::ActionSubscriber.configuration.threadpool_size,
70
57
  :user => ::ActionSubscriber.configuration.username,
71
58
  :vhost => ::ActionSubscriber.configuration.virtual_host,
72
- :automatically_recover => true,
73
- :network_recovery_interval => NETWORK_RECOVERY_INTERVAL,
74
- :recover_from_connection_close => true,
75
59
  }
76
60
  end
77
61
  private_class_method :connection_options
62
+
63
+ def self.subscriber_connections
64
+ @subscriber_connections ||= {}
65
+ end
66
+ private_class_method :subscriber_connections
78
67
  end
79
68
  end
@@ -2,7 +2,9 @@ module ActionSubscriber
2
2
  class Route
3
3
  attr_reader :acknowledgements,
4
4
  :action,
5
- :durable,
5
+ :concurrency,
6
+ :connection_name,
7
+ :durable,
6
8
  :exchange,
7
9
  :prefetch,
8
10
  :queue,
@@ -13,6 +15,8 @@ module ActionSubscriber
13
15
  def initialize(attributes)
14
16
  @acknowledgements = attributes.fetch(:acknowledgements)
15
17
  @action = attributes.fetch(:action)
18
+ @concurrency = attributes.fetch(:concurrency, 1)
19
+ @connection_name = attributes.fetch(:connection_name)
16
20
  @durable = attributes.fetch(:durable)
17
21
  @exchange = attributes.fetch(:exchange).to_s
18
22
  @prefetch = attributes.fetch(:prefetch) { ::ActionSubscriber.config.prefetch }
@@ -12,27 +12,28 @@ module ActionSubscriber
12
12
  @routes = routes
13
13
  end
14
14
 
15
- def setup_queues!
15
+ def setup_subscriptions!
16
+ fail ::RuntimeError, "you cannot setup queues multiple times, this should only happen once at startup" unless subscriptions.empty?
16
17
  routes.each do |route|
17
- queues[route] = setup_queue(route)
18
+ route.concurrency.times do
19
+ subscriptions << {
20
+ :route => route,
21
+ :queue => setup_queue(route),
22
+ }
23
+ end
18
24
  end
19
25
  end
20
26
 
21
27
  private
22
28
 
23
- def queues
24
- @queues ||= {}
29
+ def subscriptions
30
+ @subscriptions ||= []
25
31
  end
26
32
 
27
33
  def setup_queue(route)
28
- channel = ::ActionSubscriber::RabbitConnection.subscriber_connection.create_channel
29
- # Make channels threadsafe again! Believe Me!
30
- # Accessing channels from multiple threads for messsage acknowledgement will crash
31
- # a channel and stop messages from being received on that channel
32
- # this isn't very clear in the documentation for march_hare/bunny, but it is
33
- # explicitly addresses here: https://github.com/rabbitmq/rabbitmq-java-client/issues/53
34
- channel = ::ActionSubscriber::Synchronizer.new(channel)
34
+ channel = ::ActionSubscriber::RabbitConnection.with_connection(route.connection_name){ |connection| connection.create_channel }
35
35
  exchange = channel.topic(route.exchange)
36
+ # TODO go to back to the old way of creating a queue?
36
37
  queue = create_queue(channel, route.queue, :durable => route.durable)
37
38
  queue.bind(exchange, :routing_key => route.routing_key)
38
39
  queue
@@ -12,6 +12,17 @@ module ActionSubscriber
12
12
  :exchange => "events",
13
13
  }.freeze
14
14
 
15
+ def initialize
16
+ @current_connection_name = :default
17
+ end
18
+
19
+ def connection(name, settings)
20
+ ::ActionSubscriber::RabbitConnection.setup_connection(name, settings)
21
+ @current_connection_name = name
22
+ yield
23
+ @current_connection_name = :default
24
+ end
25
+
15
26
  def default_routing_key_for(route_settings)
16
27
  [
17
28
  route_settings[:publisher],
@@ -30,7 +41,7 @@ module ActionSubscriber
30
41
  end
31
42
 
32
43
  def default_routes_for(subscriber)
33
- subscriber.routes.each do |route|
44
+ subscriber.routes({:connection_name => @current_connection_name}).each do |route|
34
45
  routes << route
35
46
  end
36
47
  end
@@ -40,7 +51,7 @@ module ActionSubscriber
40
51
  end
41
52
 
42
53
  def route(subscriber, action, options = {})
43
- route_settings = DEFAULT_SETTINGS.merge(options).merge(:subscriber => subscriber, :action => action)
54
+ route_settings = DEFAULT_SETTINGS.merge(:connection_name => @current_connection_name).merge(options).merge(:subscriber => subscriber, :action => action)
44
55
  route_settings[:routing_key] ||= default_routing_key_for(route_settings)
45
56
  route_settings[:queue] ||= default_queue_for(route_settings)
46
57
  routes << Route.new(route_settings)
@@ -1,3 +1,3 @@
1
1
  module ActionSubscriber
2
- VERSION = "2.5.0.pre2"
2
+ VERSION = "3.0.0.pre1"
3
3
  end
@@ -25,9 +25,6 @@ require "action_subscriber/subscribable"
25
25
  require "action_subscriber/bunny/subscriber"
26
26
  require "action_subscriber/march_hare/subscriber"
27
27
  require "action_subscriber/babou"
28
- require "action_subscriber/publisher"
29
- require "action_subscriber/publisher/async"
30
- require "action_subscriber/synchronizer"
31
28
  require "action_subscriber/route"
32
29
  require "action_subscriber/route_set"
33
30
  require "action_subscriber/router"
@@ -81,19 +78,21 @@ module ActionSubscriber
81
78
  end
82
79
  end
83
80
 
84
- def self.setup_queues!
85
- route_set.setup_queues!
81
+ def self.setup_default_connection!
82
+ ::ActionSubscriber::RabbitConnection.setup_connection(:default, {})
83
+ end
84
+
85
+ def self.setup_subscriptions!
86
+ route_set.setup_subscriptions!
86
87
  end
87
88
 
88
89
  def self.start_queues
89
- ::ActionSubscriber::RabbitConnection.subscriber_connection
90
- setup_queues!
90
+ setup_subscriptions!
91
91
  print_subscriptions
92
92
  end
93
93
 
94
94
  def self.start_subscribers
95
- ::ActionSubscriber::RabbitConnection.subscriber_connection
96
- setup_queues!
95
+ setup_subscriptions!
97
96
  auto_subscribe!
98
97
  print_subscriptions
99
98
  end
@@ -106,21 +105,14 @@ module ActionSubscriber
106
105
  require "action_subscriber/railtie" if defined?(Rails)
107
106
  ::ActiveSupport.run_load_hooks(:action_subscriber, Base)
108
107
 
109
- # Intialize async publisher adapter
110
- ::ActionSubscriber::Publisher::Async.publisher_adapter
111
-
112
108
  ##
113
109
  # Private Implementation
114
110
  #
115
111
  def self.route_set
116
112
  @route_set ||= begin
117
- if @draw_routes_block
118
- routes = Router.draw_routes(&@draw_routes_block)
119
- RouteSet.new(routes)
120
- else
121
- logger.warn "DEPRECATION WARNING: We are inferring your routes by looking at your subscribers. This behavior is deprecated and will be removed in version 2.0. Please see the routing guide at https://github.com/mxenabled/action_subscriber/blob/master/routing.md"
122
- RouteSet.new(self.send(:default_routes))
123
- end
113
+ fail "cannot start because no routes have been defined. Please make sure that you call ActionSubscriber.draw_routes when your application loads" unless @draw_routes_block
114
+ routes = Router.draw_routes(&@draw_routes_block)
115
+ RouteSet.new(routes)
124
116
  end
125
117
  end
126
118
  private_class_method :route_set
@@ -132,8 +124,3 @@ module ActionSubscriber
132
124
  end
133
125
  private_class_method :default_routes
134
126
  end
135
-
136
- at_exit do
137
- ::ActionSubscriber::Publisher::Async.publisher_adapter.shutdown!
138
- ::ActionSubscriber::RabbitConnection.publisher_disconnect!
139
- end
@@ -32,7 +32,7 @@ describe "subscriber filters", :integration => true do
32
32
  it "runs multiple around filters" do
33
33
  $messages = [] #testing the order of things
34
34
  ::ActionSubscriber.auto_subscribe!
35
- ::ActionSubscriber::Publisher.publish("insta.first", "hEY Guyz!", "events")
35
+ ::ActivePublisher.publish("insta.first", "hEY Guyz!", "events")
36
36
 
37
37
  verify_expectation_within(1.0) do
38
38
  expect($messages).to eq [:whisper_before, :yell_before, "hEY Guyz!", :yell_after, :whisper_after]
@@ -17,7 +17,7 @@ describe "at_least_once! mode", :integration => true do
17
17
 
18
18
  it "retries a failed job until it succeeds" do
19
19
  ::ActionSubscriber.auto_subscribe!
20
- ::ActionSubscriber::Publisher.publish("gorby_puff.grumpy", "GrumpFace", "events")
20
+ ::ActivePublisher.publish("gorby_puff.grumpy", "GrumpFace", "events")
21
21
 
22
22
  verify_expectation_within(2.0) do
23
23
  expect($messages).to eq Set.new(["GrumpFace::0","GrumpFace::1","GrumpFace::2"])
@@ -17,7 +17,7 @@ describe "at_most_once! mode", :integration => true do
17
17
 
18
18
  it "does not retry a failed message" do
19
19
  ::ActionSubscriber.auto_subscribe!
20
- ::ActionSubscriber::Publisher.publish("pokemon.caught_em_all", "All Pokemon have been caught", "events")
20
+ ::ActivePublisher.publish("pokemon.caught_em_all", "All Pokemon have been caught", "events")
21
21
 
22
22
  verify_expectation_within(1.0) do
23
23
  expect($messages.size).to eq 1
@@ -7,7 +7,6 @@ class GusSubscriber < ActionSubscriber::Base
7
7
  end
8
8
 
9
9
  describe "Automatically reconnect on connection failure", :integration => true, :slow => true do
10
- let(:connection) { subscriber.connection }
11
10
  let(:draw_routes) do
12
11
  ::ActionSubscriber.draw_routes do
13
12
  default_routes_for GusSubscriber
@@ -18,7 +17,7 @@ describe "Automatically reconnect on connection failure", :integration => true,
18
17
 
19
18
  it "reconnects when a connection drops" do
20
19
  ::ActionSubscriber::auto_subscribe!
21
- ::ActionSubscriber::Publisher.publish("gus.spoke", "First", "events")
20
+ ::ActivePublisher.publish("gus.spoke", "First", "events")
22
21
  verify_expectation_within(5.0) do
23
22
  expect($messages).to eq(Set.new(["First"]))
24
23
  end
@@ -26,10 +25,10 @@ describe "Automatically reconnect on connection failure", :integration => true,
26
25
  close_all_connections!
27
26
  sleep 5.0
28
27
  verify_expectation_within(5.0) do
29
- expect(connection).to be_open
28
+ expect(::ActionSubscriber::RabbitConnection.with_connection(:default){|connection| connection.open?}).to eq(true)
30
29
  end
31
30
 
32
- ::ActionSubscriber::Publisher.publish("gus.spoke", "Second", "events")
31
+ ::ActivePublisher.publish("gus.spoke", "Second", "events")
33
32
  verify_expectation_within(5.0) do
34
33
  expect($messages).to eq(Set.new(["First", "Second"]))
35
34
  end