action_subscriber 2.5.0.pre2 → 3.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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