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 +4 -4
- data/lib/action_subscriber.rb +44 -10
- data/lib/action_subscriber/babou.rb +2 -4
- data/lib/action_subscriber/base.rb +0 -16
- data/lib/action_subscriber/bunny/subscriber.rb +7 -8
- data/lib/action_subscriber/default_routing.rb +15 -19
- data/lib/action_subscriber/dsl.rb +0 -4
- data/lib/action_subscriber/march_hare/subscriber.rb +7 -8
- data/lib/action_subscriber/route.rb +27 -0
- data/lib/action_subscriber/route_set.rb +35 -0
- data/lib/action_subscriber/router.rb +66 -0
- data/lib/action_subscriber/subscribable.rb +0 -14
- data/lib/action_subscriber/version.rb +1 -1
- data/routing.md +46 -0
- data/spec/lib/action_subscriber/dsl_spec.rb +0 -4
- data/spec/lib/action_subscriber/router_spec.rb +110 -0
- data/spec/spec_helper.rb +2 -3
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ce95bad589b12e09750cbceef880b2e4a7e4933
|
4
|
+
data.tar.gz: 4ccca08bb96b3401e798ac15a92498a85850965b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e355a6646d0b212535c6035f5ba7c02576d68474759990f35be2469f133ceeaad2d79e62017e7fca1b6d5b9712cc9edf4bb5534d261809fd6e824b864bfce60
|
7
|
+
data.tar.gz: 14ce2729c8c9cfa57d7b513a7c78ab42c7cfa928e11b033495b7bd6bfff9dc915632228f858ade345da418ef102f3f0b5f8e1e1d6af10a267972a4005b0849e3
|
data/lib/action_subscriber.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
85
|
-
|
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(
|
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
|
42
|
-
consumer = ::Bunny::Consumer.new(channel, queue, channel.generate_consumer_tag, !
|
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(
|
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
|
4
|
-
@
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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(
|
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
|
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(
|
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
|
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
|
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
|
+
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-
|
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:
|
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
|