action_subscriber 1.4.0.pre0-java → 1.5.0-java

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 042a564551cf9cba7a467fb02bfcb3ca330254d8
4
- data.tar.gz: ac3c7ceba3d7c7402198b790d9236e09005c4ca2
3
+ metadata.gz: a3422aaf739a8559ca1fe51edaf9ce6d29452b45
4
+ data.tar.gz: 88dd7271b35f2675202df563ac0f8c793dee1e0a
5
5
  SHA512:
6
- metadata.gz: 9e213f0216ceb4efcc923fdae6e4fa1b2b58f485447252b83b83531db6e51a99bc89eff6392c50dabf7ae98bc0b528f1442b9aa8454ce5a582dcb6f6f86caff0
7
- data.tar.gz: dc64b8f4434ae8d41bf56bb8fe53080c6131554576ff42b5eb7e23945d640f82afdea203a99106ca73edf8f08e6cf649efecb09d463b7e69c65ee89cacb9c909
6
+ metadata.gz: 0dd91629e3d5a50258614402557b7117e7f296d9991ee8c8859bfc4e67225ac2aede2178f3e5e8318f66fb04f0de89b856eac9e5467bac040ef1dfdf5cea11fd
7
+ data.tar.gz: 4c35a48ca8b97e2b3163b890f43ae5d0d1965d4b63384e625dd1a4e5bf86d0313a650a0b66d4a4cc37d5fa0055946c6cf178c1d7e57eca7346f80957bdc14033
@@ -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.pre0"
2
+ VERSION = "1.5.0"
3
3
  end
data/routing.md ADDED
@@ -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
data/spec/spec_helper.rb CHANGED
@@ -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.pre0
4
+ version: 1.5.0
5
5
  platform: java
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-22 00:00:00.000000000 Z
15
+ date: 2015-11-20 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  requirement: !ruby/object:Gem::Requirement
@@ -214,10 +214,14 @@ files:
214
214
  - lib/action_subscriber/publisher.rb
215
215
  - lib/action_subscriber/rabbit_connection.rb
216
216
  - lib/action_subscriber/railtie.rb
217
+ - lib/action_subscriber/route.rb
218
+ - lib/action_subscriber/route_set.rb
219
+ - lib/action_subscriber/router.rb
217
220
  - lib/action_subscriber/rspec.rb
218
221
  - lib/action_subscriber/subscribable.rb
219
222
  - lib/action_subscriber/threadpool.rb
220
223
  - lib/action_subscriber/version.rb
224
+ - routing.md
221
225
  - spec/integration/around_filters_spec.rb
222
226
  - spec/integration/at_least_once_spec.rb
223
227
  - spec/integration/at_most_once_spec.rb
@@ -237,6 +241,7 @@ files:
237
241
  - spec/lib/action_subscriber/middleware/router_spec.rb
238
242
  - spec/lib/action_subscriber/middleware/runner_spec.rb
239
243
  - spec/lib/action_subscriber/publisher_spec.rb
244
+ - spec/lib/action_subscriber/router_spec.rb
240
245
  - spec/lib/action_subscriber/subscribable_spec.rb
241
246
  - spec/lib/action_subscriber/threadpool_spec.rb
242
247
  - spec/spec_helper.rb
@@ -256,12 +261,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
256
261
  version: '0'
257
262
  required_rubygems_version: !ruby/object:Gem::Requirement
258
263
  requirements:
259
- - - ">"
264
+ - - ">="
260
265
  - !ruby/object:Gem::Version
261
- version: 1.3.1
266
+ version: '0'
262
267
  requirements: []
263
268
  rubyforge_project:
264
- rubygems_version: 2.4.8
269
+ rubygems_version: 2.5.0
265
270
  signing_key:
266
271
  specification_version: 4
267
272
  summary: ActionSubscriber is a DSL that allows a rails app to consume messages from a RabbitMQ broker.
@@ -285,6 +290,7 @@ test_files:
285
290
  - spec/lib/action_subscriber/middleware/router_spec.rb
286
291
  - spec/lib/action_subscriber/middleware/runner_spec.rb
287
292
  - spec/lib/action_subscriber/publisher_spec.rb
293
+ - spec/lib/action_subscriber/router_spec.rb
288
294
  - spec/lib/action_subscriber/subscribable_spec.rb
289
295
  - spec/lib/action_subscriber/threadpool_spec.rb
290
296
  - spec/spec_helper.rb