action_subscriber 1.4.0 → 1.5.0.pre0

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
  SHA1:
3
- metadata.gz: 7c33e2d02325c43757e2d201acb4fd81b15c3ff8
4
- data.tar.gz: 5cf829f7a27a291114b9c2f10e795544a137e73b
3
+ metadata.gz: 5ce95bad589b12e09750cbceef880b2e4a7e4933
4
+ data.tar.gz: 4ccca08bb96b3401e798ac15a92498a85850965b
5
5
  SHA512:
6
- metadata.gz: a4a387861549ba8a6ea1270edc617b7d53c0271938f5469916340a96a93d259e33d383101805d3a5a739a4a0ae22004db26caa1298f58faa64caf0d1e55c213c
7
- data.tar.gz: 12340e4b8328b4db94bd1a1d36dd8a8c10a574a08d8c81c05666d14769696a664998b2f93d0f08860ecbf82537af1771c764cfac98c69c2fe87471d80318c600
6
+ metadata.gz: 1e355a6646d0b212535c6035f5ba7c02576d68474759990f35be2469f133ceeaad2d79e62017e7fca1b6d5b9712cc9edf4bb5534d261809fd6e824b864bfce60
7
+ data.tar.gz: 14ce2729c8c9cfa57d7b513a7c78ab42c7cfa928e11b033495b7bd6bfff9dc915632228f858ade345da418ef102f3f0b5f8e1e1d6af10a267972a4005b0849e3
@@ -22,6 +22,9 @@ require "action_subscriber/bunny/subscriber"
22
22
  require "action_subscriber/march_hare/subscriber"
23
23
  require "action_subscriber/babou"
24
24
  require "action_subscriber/publisher"
25
+ require "action_subscriber/route"
26
+ require "action_subscriber/route_set"
27
+ require "action_subscriber/router"
25
28
  require "action_subscriber/threadpool"
26
29
  require "action_subscriber/base"
27
30
 
@@ -35,18 +38,14 @@ module ActionSubscriber
35
38
  #
36
39
  def self.auto_pop!
37
40
  return if ::ActionSubscriber::Threadpool.busy?
38
- ::ActionSubscriber::Base.inherited_classes.each do |klass|
39
- klass.auto_pop!
40
- end
41
+ route_set.auto_pop!
41
42
  end
42
43
 
43
44
  # Loop over all subscribers and register each as
44
45
  # a subscriber.
45
46
  #
46
47
  def self.auto_subscribe!
47
- ::ActionSubscriber::Base.inherited_classes.each do |klass|
48
- klass.auto_subscribe!
49
- end
48
+ route_set.auto_subscribe!
50
49
  end
51
50
 
52
51
  def self.configuration
@@ -57,14 +56,26 @@ module ActionSubscriber
57
56
  yield(configuration) if block_given?
58
57
  end
59
58
 
59
+ def self.draw_routes(&block)
60
+ routes = Router.draw_routes(&block)
61
+ @route_set = RouteSet.new(routes)
62
+ end
63
+
60
64
  def self.print_subscriptions
61
- ::ActionSubscriber::Base.print_subscriptions
65
+ puts configuration.inspect
66
+ route_set.routes.group_by(&:subscriber).each do |subscriber, routes|
67
+ puts subscriber.name
68
+ routes.each do |route|
69
+ puts " -- method: #{route.action}"
70
+ puts " -- exchange: #{route.exchange}"
71
+ puts " -- queue: #{route.queue}"
72
+ puts " -- routing_key: #{route.routing_key}"
73
+ end
74
+ end
62
75
  end
63
76
 
64
77
  def self.setup_queues!
65
- ::ActionSubscriber::Base.inherited_classes.each do |klass|
66
- klass.setup_queues!
67
- end
78
+ route_set.setup_queues!
68
79
  end
69
80
 
70
81
  def self.start_queues
@@ -80,6 +91,10 @@ module ActionSubscriber
80
91
  print_subscriptions
81
92
  end
82
93
 
94
+ def self.stop_subscribers!
95
+ route_set.cancel_consumers!
96
+ end
97
+
83
98
  ##
84
99
  # Class aliases
85
100
  #
@@ -91,6 +106,25 @@ module ActionSubscriber
91
106
  config
92
107
 
93
108
  ::ActiveSupport.run_load_hooks(:action_subscriber, Base)
109
+
110
+ ##
111
+ # Private Implementation
112
+ #
113
+ def self.route_set
114
+ @route_set ||= begin
115
+ puts "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"
116
+ RouteSet.new(self.send(:default_routes))
117
+ end
118
+ end
119
+ private_class_method :route_set
120
+
121
+ def self.default_routes
122
+ ::ActionSubscriber::Base.inherited_classes.flat_map do |klass|
123
+ klass.routes
124
+ end
125
+ end
126
+ private_class_method :default_routes
127
+
94
128
  end
95
129
 
96
130
  require "action_subscriber/railtie" if defined?(Rails)
@@ -81,10 +81,8 @@ module ActionSubscriber
81
81
  def self.stop_receving_messages!
82
82
  @shutting_down = true
83
83
  ::Thread.new do
84
- ::ActionSubscriber::Base.inherited_classes.each do |subscriber|
85
- subscriber.cancel_consumers!
86
- puts "finished cancelling consumers"
87
- end
84
+ ::ActionSubscriber.stop_subscribers!
85
+ puts "stopped all subscribers"
88
86
  end.join
89
87
  end
90
88
 
@@ -3,11 +3,6 @@ module ActionSubscriber
3
3
  extend ::ActionSubscriber::DefaultRouting
4
4
  extend ::ActionSubscriber::DSL
5
5
  extend ::ActionSubscriber::Subscribable
6
- if ::RUBY_PLATFORM == "java"
7
- extend ::ActionSubscriber::MarchHare::Subscriber
8
- else
9
- extend ::ActionSubscriber::Bunny::Subscriber
10
- end
11
6
 
12
7
  ##
13
8
  # Private Attributes
@@ -49,17 +44,6 @@ module ActionSubscriber
49
44
  @_inherited_classes ||= []
50
45
  end
51
46
 
52
- def self.print_subscriptions
53
- puts ::ActionSubscriber.configuration.inspect
54
- puts ""
55
-
56
- inherited_classes.each do |klass|
57
- puts klass.inspect
58
- end
59
-
60
- nil
61
- end
62
-
63
47
  ##
64
48
  # Class Aliases
65
49
  #
@@ -6,7 +6,6 @@ module ActionSubscriber
6
6
  end
7
7
 
8
8
  def cancel_consumers!
9
- puts "cancelling consumers for #{self}"
10
9
  bunny_consumers.each(&:cancel)
11
10
  end
12
11
 
@@ -15,8 +14,8 @@ module ActionSubscriber
15
14
  # of times we will pop each time we poll the broker
16
15
  times_to_pop = [::ActionSubscriber::Threadpool.ready_size, ::ActionSubscriber.config.times_to_pop].min
17
16
  times_to_pop.times do
18
- queues.each do |queue|
19
- delivery_info, properties, encoded_payload = queue.pop(queue_subscription_options)
17
+ queues.each do |route, queue|
18
+ delivery_info, properties, encoded_payload = queue.pop(route.queue_subscription_options)
20
19
  next unless encoded_payload # empty queue
21
20
  ::ActiveSupport::Notifications.instrument "popped_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
22
21
  properties = {
@@ -29,17 +28,17 @@ module ActionSubscriber
29
28
  :routing_key => delivery_info.routing_key,
30
29
  :queue => queue.name,
31
30
  }
32
- env = ::ActionSubscriber::Middleware::Env.new(self, encoded_payload, properties)
31
+ env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
33
32
  enqueue_env(env)
34
33
  end
35
34
  end
36
35
  end
37
36
 
38
37
  def auto_subscribe!
39
- queues.each do |queue|
38
+ queues.each do |route, queue|
40
39
  channel = queue.channel
41
- channel.prefetch(::ActionSubscriber.config.prefetch) if acknowledge_messages?
42
- consumer = ::Bunny::Consumer.new(channel, queue, channel.generate_consumer_tag, !acknowledge_messages?)
40
+ channel.prefetch(::ActionSubscriber.config.prefetch) if route.acknowledgements?
41
+ consumer = ::Bunny::Consumer.new(channel, queue, channel.generate_consumer_tag, !route.acknowledgements?)
43
42
  consumer.on_delivery do |delivery_info, properties, encoded_payload|
44
43
  ::ActiveSupport::Notifications.instrument "received_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
45
44
  properties = {
@@ -52,7 +51,7 @@ module ActionSubscriber
52
51
  :routing_key => delivery_info.routing_key,
53
52
  :queue => queue.name,
54
53
  }
55
- env = ::ActionSubscriber::Middleware::Env.new(self, encoded_payload, properties)
54
+ env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
56
55
  enqueue_env(env)
57
56
  end
58
57
  bunny_consumers << consumer
@@ -1,25 +1,21 @@
1
1
  module ActionSubscriber
2
2
  module DefaultRouting
3
- def queues
4
- @_queues ||= []
5
- end
6
-
7
- def setup_queue!(method_name, exchange_name)
8
- queue_name = queue_name_for_method(method_name)
9
- routing_key_name = routing_key_name_for_method(method_name)
10
-
11
- channel = connection.create_channel
12
- exchange = channel.topic(exchange_name)
13
- queue = channel.queue(queue_name)
14
- queue.bind(exchange, :routing_key => routing_key_name)
15
- return queue
16
- end
17
-
18
- def setup_queues!
19
- exchange_names.each do |exchange_name|
20
- subscribable_methods.each do |method_name|
21
- queues << setup_queue!(method_name, exchange_name)
3
+ def routes
4
+ @routes ||= begin
5
+ routes = []
6
+ exchange_names.each do |exchange_name|
7
+ subscribable_methods.each do |method_name|
8
+ routes << ActionSubscriber::Route.new({
9
+ acknowledgements: acknowledge_messages?,
10
+ action: method_name,
11
+ exchange: exchange_name,
12
+ routing_key: routing_key_name_for_method(method_name),
13
+ subscriber: self,
14
+ queue: queue_name_for_method(method_name),
15
+ })
16
+ end
22
17
  end
18
+ routes
23
19
  end
24
20
  end
25
21
  end
@@ -59,10 +59,6 @@ module ActionSubscriber
59
59
  @_queue_names ||= {}
60
60
  end
61
61
 
62
- def queue_subscription_options
63
- @_queue_subscription_options ||= { :manual_ack => acknowledge_messages? }
64
- end
65
-
66
62
  def remote_application_name(name = nil)
67
63
  @_remote_application_name = name if name
68
64
  @_remote_application_name
@@ -2,7 +2,6 @@ module ActionSubscriber
2
2
  module MarchHare
3
3
  module Subscriber
4
4
  def cancel_consumers!
5
- puts "cancelling consumers for #{self}"
6
5
  march_hare_consumers.each(&:cancel)
7
6
  end
8
7
 
@@ -11,8 +10,8 @@ module ActionSubscriber
11
10
  # of times we will pop each time we poll the broker
12
11
  times_to_pop = [::ActionSubscriber::Threadpool.ready_size, ::ActionSubscriber.config.times_to_pop].min
13
12
  times_to_pop.times do
14
- queues.each do |queue|
15
- metadata, encoded_payload = queue.pop(queue_subscription_options)
13
+ queues.each do |route,queue|
14
+ metadata, encoded_payload = queue.pop(route.queue_subscription_options)
16
15
  next unless encoded_payload
17
16
  ::ActiveSupport::Notifications.instrument "popped_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
18
17
  properties = {
@@ -25,7 +24,7 @@ module ActionSubscriber
25
24
  :routing_key => metadata.routing_key,
26
25
  :queue => queue.name,
27
26
  }
28
- env = ::ActionSubscriber::Middleware::Env.new(self, encoded_payload, properties)
27
+ env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
29
28
  enqueue_env(env)
30
29
  end
31
30
  end
@@ -35,9 +34,9 @@ module ActionSubscriber
35
34
  end
36
35
 
37
36
  def auto_subscribe!
38
- queues.each do |queue|
39
- queue.channel.prefetch = ::ActionSubscriber.config.prefetch if acknowledge_messages?
40
- consumer = queue.subscribe(queue_subscription_options) do |metadata, encoded_payload|
37
+ queues.each do |route,queue|
38
+ queue.channel.prefetch = ::ActionSubscriber.config.prefetch if route.acknowledgements?
39
+ consumer = queue.subscribe(route.queue_subscription_options) do |metadata, encoded_payload|
41
40
  ::ActiveSupport::Notifications.instrument "received_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
42
41
  properties = {
43
42
  :channel => queue.channel,
@@ -49,7 +48,7 @@ module ActionSubscriber
49
48
  :routing_key => metadata.routing_key,
50
49
  :queue => queue.name,
51
50
  }
52
- env = ::ActionSubscriber::Middleware::Env.new(self, encoded_payload, properties)
51
+ env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
53
52
  enqueue_env(env)
54
53
  end
55
54
 
@@ -0,0 +1,27 @@
1
+ module ActionSubscriber
2
+ class Route
3
+ attr_reader :acknowledgements,
4
+ :action,
5
+ :exchange,
6
+ :routing_key,
7
+ :subscriber,
8
+ :queue
9
+
10
+ def initialize(attributes)
11
+ @acknowledgements = attributes.fetch(:acknowledgements)
12
+ @action = attributes.fetch(:action)
13
+ @exchange = attributes.fetch(:exchange).to_s
14
+ @routing_key = attributes.fetch(:routing_key)
15
+ @subscriber = attributes.fetch(:subscriber)
16
+ @queue = attributes.fetch(:queue)
17
+ end
18
+
19
+ def acknowledgements?
20
+ @acknowledgements
21
+ end
22
+
23
+ def queue_subscription_options
24
+ { :manual_ack => acknowledgements? }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ module ActionSubscriber
2
+ class RouteSet
3
+ if ::RUBY_PLATFORM == "java"
4
+ include ::ActionSubscriber::MarchHare::Subscriber
5
+ else
6
+ include ::ActionSubscriber::Bunny::Subscriber
7
+ end
8
+
9
+ attr_reader :routes
10
+
11
+ def initialize(routes)
12
+ @routes = routes
13
+ end
14
+
15
+ def setup_queues!
16
+ routes.each do |route|
17
+ queues[route] = setup_queue(route)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def queues
24
+ @queues ||= {}
25
+ end
26
+
27
+ def setup_queue(route)
28
+ channel = ::ActionSubscriber::RabbitConnection.subscriber_connection.create_channel
29
+ exchange = channel.topic(route.exchange)
30
+ queue = channel.queue(route.queue)
31
+ queue.bind(exchange, :routing_key => route.routing_key)
32
+ queue
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,66 @@
1
+ module ActionSubscriber
2
+ class Router
3
+ def self.draw_routes(&block)
4
+ router = self.new
5
+ router.instance_eval(&block)
6
+ router.routes
7
+ end
8
+
9
+ DEFAULT_SETTINGS = {
10
+ :acknowledgements => false,
11
+ :exchange => "events",
12
+ }.freeze
13
+
14
+ def default_routing_key_for(route_settings)
15
+ [
16
+ route_settings[:publisher],
17
+ resource_name(route_settings),
18
+ route_settings[:action].to_s,
19
+ ].compact.join(".")
20
+ end
21
+
22
+ def default_queue_for(route_settings)
23
+ [
24
+ local_application_name,
25
+ route_settings[:publisher],
26
+ resource_name(route_settings),
27
+ route_settings[:action].to_s,
28
+ ].compact.join(".")
29
+ end
30
+
31
+ def default_routes_for(subscriber)
32
+ subscriber.routes.each do |route|
33
+ routes << route
34
+ end
35
+ end
36
+
37
+ def resource_name(route_settings)
38
+ route_settings[:subscriber].name.underscore.gsub(/_subscriber/, "").to_s
39
+ end
40
+
41
+ def route(subscriber, action, options = {})
42
+ route_settings = DEFAULT_SETTINGS.merge(options).merge(:subscriber => subscriber, :action => action)
43
+ route_settings[:routing_key] ||= default_routing_key_for(route_settings)
44
+ route_settings[:queue] ||= default_queue_for(route_settings)
45
+ routes << Route.new(route_settings)
46
+ end
47
+
48
+ def routes
49
+ @routes ||= []
50
+ end
51
+
52
+ def local_application_name
53
+ @_local_application_name ||= begin
54
+ local_application_name = case
55
+ when ENV['APP_NAME'] then
56
+ ENV['APP_NAME'].to_s.dup
57
+ when defined?(::Rails) then
58
+ ::Rails.application.class.parent_name.dup
59
+ else
60
+ raise "Define an application name (ENV['APP_NAME'])"
61
+ end
62
+ local_application_name.downcase
63
+ end
64
+ end
65
+ end
66
+ end
@@ -46,20 +46,6 @@ module ActionSubscriber
46
46
  @_local_application_name
47
47
  end
48
48
 
49
- def inspect
50
- inspection_string = "#{self.name}\n"
51
- exchange_names.each do |exchange_name|
52
- inspection_string << " -- exchange: #{exchange_name}\n"
53
- subscribable_methods.each do |method|
54
- inspection_string << " -- method: #{method}\n"
55
- inspection_string << " -- queue: #{queue_names[method]}\n"
56
- inspection_string << " -- routing_key: #{routing_key_names[method]}\n"
57
- inspection_string << "\n"
58
- end
59
- end
60
- return inspection_string
61
- end
62
-
63
49
  # Build the `queue` for a given method.
64
50
  #
65
51
  # If the queue name is not set, the queue name is
@@ -1,3 +1,3 @@
1
1
  module ActionSubscriber
2
- VERSION = "1.4.0"
2
+ VERSION = "1.5.0.pre0"
3
3
  end
@@ -0,0 +1,46 @@
1
+ # Routing In ActionSubscriber
2
+
3
+ ActionSubscriber used to automatically discover all your subscribers and infer all their routes based on a default set of rules<sup>[1](#footnotes)</sup>. As of ActionSubscriber `1.5.0` this behavior is deprecated in favor of having the application draw its routes explicitly.
4
+
5
+ ## The Simple Upgrade Path
6
+
7
+ The simplest way to draw your routes is to create a `config/initializers/action_subscriber.rb` file and ask the router to setup default routes like this:
8
+
9
+ ```ruby
10
+ ::ActionSubscriber.draw_routes do
11
+ default_routes_for ::UserSubscriber
12
+ default_routes_for ::NotificationSubscriber
13
+ end
14
+ ```
15
+
16
+ This is the easiest migration path for existing users to follow, but it doesn't allow for things like mixing which exchange you are subscribing to between different actions.
17
+
18
+ ## Custom Routes
19
+
20
+ You can also specify custom routes for your subscribers when you want more flexibility.
21
+
22
+ ```ruby
23
+ ::ActionSubscriber.draw_routes do
24
+ default_routes_for ::UserSubscriber
25
+
26
+ route ::NotificationSubscriber, :created, :publisher => :newman, :exchange => :events
27
+ route ::NotificationSubscriber, :send, :publisher => :newman, :exchange => :action
28
+ end
29
+ ```
30
+
31
+ ## Options For Routes
32
+
33
+ The `route` method supports the following options:
34
+
35
+ * `acknowledgements` this toggles whether this route is expected to provide an acknowledgment (default `false`)
36
+ * This is the equivalent of calling `at_most_once!`, `at_least_once!` or `manual_acknowledgement!` in your subscriber class
37
+ * `exchange` specify which exchange you expect messages to be published to (default `"events"`)
38
+ * This is the equivalent of calling `exchange :actions` in your subscriber
39
+ * `publisher` this will prefix your queue and routing key with the publishers name
40
+ * This is the equivalent of puting `publisher :foo` in your subscriber
41
+ * `queue` specifies which queue you will subscribe to rather than letting ActionSubscriber infer it from the name of the subscriber and action
42
+ * `routing_key` specifies the routing key that will be bound to your queue
43
+
44
+ <h3 id="footnotes">Footnotes</h3>
45
+
46
+ * __1__ the old behavior of discovering and inferring routes for subscribers will be supported until the 2.0 version of ActionSubscriber. When no routes are drawn before calling `setup_queues!` we will print a deprecation warning and infer the routes for you.
@@ -9,10 +9,6 @@ describe ::ActionSubscriber::DSL do
9
9
  it "acknowledges messages" do
10
10
  expect(subscriber.acknowledge_messages?).to eq(true)
11
11
  end
12
-
13
- it "returns expected queue subscription options" do
14
- expect(subscriber.queue_subscription_options).to eq( :manual_ack => true )
15
- end
16
12
  end
17
13
 
18
14
  context "when at_most_once! is set" do
@@ -0,0 +1,110 @@
1
+ describe ActionSubscriber::Router do
2
+ class FakeSubscriber; end
3
+
4
+ it "can specify basic routes" do
5
+ routes = described_class.draw_routes do
6
+ route FakeSubscriber, :foo
7
+ end
8
+
9
+ expect(routes.first.acknowledgements).to eq(false)
10
+ expect(routes.first.action).to eq(:foo)
11
+ expect(routes.first.exchange).to eq("events")
12
+ expect(routes.first.routing_key).to eq("fake.foo")
13
+ expect(routes.first.subscriber).to eq(FakeSubscriber)
14
+ expect(routes.first.queue).to eq("alice.fake.foo")
15
+ end
16
+
17
+ it "can specify a publisher" do
18
+ routes = described_class.draw_routes do
19
+ route FakeSubscriber, :bluff, :publisher => :amigo
20
+ end
21
+
22
+ expect(routes.first.acknowledgements).to eq(false)
23
+ expect(routes.first.action).to eq(:bluff)
24
+ expect(routes.first.exchange).to eq("events")
25
+ expect(routes.first.routing_key).to eq("amigo.fake.bluff")
26
+ expect(routes.first.subscriber).to eq(FakeSubscriber)
27
+ expect(routes.first.queue).to eq("alice.amigo.fake.bluff")
28
+ end
29
+
30
+ it "can specify an exchange" do
31
+ routes = described_class.draw_routes do
32
+ route FakeSubscriber, :crashed, :exchange => :actions
33
+ end
34
+
35
+ expect(routes.first.acknowledgements).to eq(false)
36
+ expect(routes.first.action).to eq(:crashed)
37
+ expect(routes.first.exchange).to eq("actions")
38
+ expect(routes.first.routing_key).to eq("fake.crashed")
39
+ expect(routes.first.subscriber).to eq(FakeSubscriber)
40
+ expect(routes.first.queue).to eq("alice.fake.crashed")
41
+ end
42
+
43
+ it "can specify acknowledgements" do
44
+ routes = described_class.draw_routes do
45
+ route FakeSubscriber, :foo, :acknowledgements => true
46
+ end
47
+
48
+ expect(routes.first.acknowledgements).to eq(true)
49
+ expect(routes.first.action).to eq(:foo)
50
+ expect(routes.first.exchange).to eq("events")
51
+ expect(routes.first.routing_key).to eq("fake.foo")
52
+ expect(routes.first.subscriber).to eq(FakeSubscriber)
53
+ expect(routes.first.queue).to eq("alice.fake.foo")
54
+ end
55
+
56
+ it "can specify the queue" do
57
+ routes = described_class.draw_routes do
58
+ route FakeSubscriber, :foo, :publisher => "russell", :queue => "i-am-your-father"
59
+ end
60
+
61
+ expect(routes.first.acknowledgements).to eq(false)
62
+ expect(routes.first.action).to eq(:foo)
63
+ expect(routes.first.exchange).to eq("events")
64
+ expect(routes.first.routing_key).to eq("russell.fake.foo")
65
+ expect(routes.first.subscriber).to eq(FakeSubscriber)
66
+ expect(routes.first.queue).to eq("i-am-your-father")
67
+ end
68
+
69
+ it "can specify the routing key" do
70
+ routes = described_class.draw_routes do
71
+ route FakeSubscriber, :foo, :publisher => "russell", :routing_key => "make.it.so"
72
+ end
73
+
74
+ expect(routes.first.acknowledgements).to eq(false)
75
+ expect(routes.first.action).to eq(:foo)
76
+ expect(routes.first.exchange).to eq("events")
77
+ expect(routes.first.routing_key).to eq("make.it.so")
78
+ expect(routes.first.subscriber).to eq(FakeSubscriber)
79
+ expect(routes.first.queue).to eq("alice.russell.fake.foo")
80
+ end
81
+
82
+ it "can infer routes based on the default routing rules" do
83
+ class SparkleSubscriber < ::ActionSubscriber::Base
84
+ at_most_once!
85
+ publisher :tommy
86
+ exchange :party
87
+
88
+ def bright; end
89
+ def dim; end
90
+ end
91
+
92
+ routes = described_class.draw_routes do
93
+ default_routes_for SparkleSubscriber
94
+ end
95
+
96
+ expect(routes.size).to eq(2)
97
+ expect(routes.first.acknowledgements).to eq(true)
98
+ expect(routes.first.action).to eq(:bright)
99
+ expect(routes.first.exchange).to eq("party")
100
+ expect(routes.first.routing_key).to eq("tommy.sparkle.bright")
101
+ expect(routes.first.subscriber).to eq(SparkleSubscriber)
102
+ expect(routes.first.queue).to eq("alice.tommy.sparkle.bright")
103
+ expect(routes.last.acknowledgements).to eq(true)
104
+ expect(routes.last.action).to eq(:dim)
105
+ expect(routes.last.exchange).to eq("party")
106
+ expect(routes.last.routing_key).to eq("tommy.sparkle.dim")
107
+ expect(routes.last.subscriber).to eq(SparkleSubscriber)
108
+ expect(routes.last.queue).to eq("alice.tommy.sparkle.dim")
109
+ end
110
+ end
@@ -24,10 +24,9 @@ RSpec.configure do |config|
24
24
  ::ActionSubscriber.setup_queues!
25
25
  end
26
26
  config.after(:each, :integration => true) do
27
+ ::ActionSubscriber.stop_subscribers!
27
28
  ::ActionSubscriber::RabbitConnection.subscriber_disconnect!
28
- ::ActionSubscriber::Base.inherited_classes.each do |klass|
29
- klass.instance_variable_set("@_queues", nil)
30
- end
29
+ ::ActionSubscriber.instance_variable_set("@route_set", nil)
31
30
  end
32
31
  end
33
32
 
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: 1.4.0
4
+ version: 1.5.0.pre0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Stien
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-10-28 00:00:00.000000000 Z
15
+ date: 2015-11-12 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport
@@ -215,10 +215,14 @@ files:
215
215
  - lib/action_subscriber/publisher.rb
216
216
  - lib/action_subscriber/rabbit_connection.rb
217
217
  - lib/action_subscriber/railtie.rb
218
+ - lib/action_subscriber/route.rb
219
+ - lib/action_subscriber/route_set.rb
220
+ - lib/action_subscriber/router.rb
218
221
  - lib/action_subscriber/rspec.rb
219
222
  - lib/action_subscriber/subscribable.rb
220
223
  - lib/action_subscriber/threadpool.rb
221
224
  - lib/action_subscriber/version.rb
225
+ - routing.md
222
226
  - spec/integration/around_filters_spec.rb
223
227
  - spec/integration/at_least_once_spec.rb
224
228
  - spec/integration/at_most_once_spec.rb
@@ -238,6 +242,7 @@ files:
238
242
  - spec/lib/action_subscriber/middleware/router_spec.rb
239
243
  - spec/lib/action_subscriber/middleware/runner_spec.rb
240
244
  - spec/lib/action_subscriber/publisher_spec.rb
245
+ - spec/lib/action_subscriber/router_spec.rb
241
246
  - spec/lib/action_subscriber/subscribable_spec.rb
242
247
  - spec/lib/action_subscriber/threadpool_spec.rb
243
248
  - spec/spec_helper.rb
@@ -257,9 +262,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
257
262
  version: '0'
258
263
  required_rubygems_version: !ruby/object:Gem::Requirement
259
264
  requirements:
260
- - - ">="
265
+ - - ">"
261
266
  - !ruby/object:Gem::Version
262
- version: '0'
267
+ version: 1.3.1
263
268
  requirements: []
264
269
  rubyforge_project:
265
270
  rubygems_version: 2.4.8
@@ -287,6 +292,7 @@ test_files:
287
292
  - spec/lib/action_subscriber/middleware/router_spec.rb
288
293
  - spec/lib/action_subscriber/middleware/runner_spec.rb
289
294
  - spec/lib/action_subscriber/publisher_spec.rb
295
+ - spec/lib/action_subscriber/router_spec.rb
290
296
  - spec/lib/action_subscriber/subscribable_spec.rb
291
297
  - spec/lib/action_subscriber/threadpool_spec.rb
292
298
  - spec/spec_helper.rb